This commit is contained in:
2026-02-12 22:15:15 +08:00
parent 47a5cff08b
commit 502c6efedc
58 changed files with 2114 additions and 708 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 718 KiB

After

Width:  |  Height:  |  Size: 744 KiB

View File

@@ -0,0 +1,411 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1014519456890440729
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2273870521618690535}
- component: {fileID: 1047330333873833263}
- component: {fileID: 3252086970450389204}
- component: {fileID: 4968772184202955189}
- component: {fileID: 8186953721405597799}
- component: {fileID: 7213117712083895936}
m_Layer: 0
m_Name: VideoPlayerComponent
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2273870521618690535
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1014519456890440729}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1047330333873833263
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1014519456890440729}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 638c870cac4da414fba921606d504407, type: 3}
m_Name:
m_EditorClassIdentifier:
_mediaSource: 1
_mediaReference: {fileID: 11400000, guid: 7b8a48f17a76b0d449f396690db75ebf, type: 2}
_mediaPath:
_pathType: 0
_path:
_fallbackMediaHints:
transparency: 0
alphaPacking: 0
stereoPacking: 0
_autoOpen: 1
_autoPlayOnStart: 0
_loop: 1
_audioVolume: 1
_audioBalance: 0
_audioMuted: 0
_playbackRate: 1
_useResampler: 0
_resampleMode: 0
_resampleBufferSize: 5
_videoMapping: 0
_textureFilterMode: 1
_textureWrapMode: 1
_textureAnisoLevel: 0
_sideloadSubtitles: 0
_subtitlePath:
_pathType: 2
_path:
_audioHeadTransform: {fileID: 0}
_audioFocusEnabled: 0
_audioFocusTransform: {fileID: 0}
_audioFocusWidthDegrees: 90
_audioFocusOffLevelDB: 0
_httpHeaders:
httpHeaders: []
_keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
_events:
m_PersistentCalls:
m_Calls: []
_eventMask: -1
_pauseMediaOnAppPause: 1
_playMediaOnAppUnpause: 1
_persistent: 0
_forceFileFormat: 0
_optionsWindows:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
videoApi: 0
useHardwareDecoding: 1
useRendererSync: 1
useTextureMips: 0
use10BitTextures: 0
hintAlphaChannel: 0
useLowLatency: 0
useCustomMovParser: 0
useHapNotchLC: 0
useStereoDetection: 1
useTextTrackSupport: 1
useFacebookAudio360Support: 1
useAudioDelay: 0
forceAudioOutputDeviceName:
preferredFilters: []
_audioMode: 0
audio360ChannelMode: 0
startWithHighestBitrate: 0
useLowLiveLatency: 0
parallelFrameCount: 3
prerollFrameCount: 4
useUnityAudio: 0
enableAudio360: 0
_options_macOS:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
textureFormat: 0
_audioMode: 0
_flags: 0
maximumPlaybackRate: 2
_preferredPeakBitRate: 0
_preferredPeakBitRateUnits: 1
_preferredForwardBufferDuration: 0
_preferredMaximumResolution: 0
_customPreferredMaximumResolution: {x: 0, y: 0}
_options_iOS:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
textureFormat: 0
_audioMode: 0
_flags: 0
maximumPlaybackRate: 2
_preferredPeakBitRate: 0
_preferredPeakBitRateUnits: 1
_preferredForwardBufferDuration: 0
_preferredMaximumResolution: 0
_customPreferredMaximumResolution: {x: 0, y: 0}
_options_tvOS:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
textureFormat: 0
_audioMode: 0
_flags: 0
maximumPlaybackRate: 2
_preferredPeakBitRate: 0
_preferredPeakBitRateUnits: 1
_preferredForwardBufferDuration: 0
_preferredMaximumResolution: 0
_customPreferredMaximumResolution: {x: 0, y: 0}
_options_visionOS:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
textureFormat: 0
_audioMode: 0
_flags: 0
maximumPlaybackRate: 2
_preferredPeakBitRate: 0
_preferredPeakBitRateUnits: 1
_preferredForwardBufferDuration: 0
_preferredMaximumResolution: 0
_customPreferredMaximumResolution: {x: 0, y: 0}
_optionsAndroid:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
videoOutputMode: 0
textureFormat: 0
_generateMipmaps: 0
_audioMode: 0
_preferredMaximumResolution: 3
_customPreferredMaximumResolution: {x: 0, y: 0}
_preferredPeakBitRate: 16
_preferredPeakBitRateUnits: 2
videoApi: 2
showPosterFrame: 0
audio360ChannelMode: 0
audio360LatencyMS: 0
preferSoftwareDecoder: 0
forceRtpTCP: 0
forceEnableMediaCodecAsynchronousQueueing: 0
allowUnsupportedVideoTrackVariants: 0
fileOffset: 0
startWithHighestBitrate: 1
minBufferMs: 10000
maxBufferMs: 50000
bufferForPlaybackMs: 1000
bufferForPlaybackAfterRebufferMs: 2000
prioritiseTimeOverSize: 0
useFastOesPath: 0
audioOutput: 0
blitTextureFiltering: 0
forceEnableMediaCodecAsyncQueueing: 0
enableAudio360: 0
_optionsOpenHarmony:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
textureFormat: 0
_generateMipmapsOH: 0
_useNormalizedOHMUrl: 1
_audioMode: 0
_preferredMaximumResolution: 0
_customPreferredMaximumResolution: {x: 0, y: 0}
_optionsWindowsUWP:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
useHardwareDecoding: 1
useRendererSync: 1
useTextureMips: 0
use10BitTextures: 0
hintOutput10Bit: 0
useLowLatency: 0
videoApi: 1
_audioMode: 0
audio360ChannelMode: 0
startWithHighestBitrate: 0
useLowLiveLatency: 0
_optionsWebGL:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
externalLibrary: 0
useTextureMips: 0
_audioMode: 0
m_VideoPath:
m_VideoLocation: 2
--- !u!82 &3252086970450389204
AudioSource:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1014519456890440729}
m_Enabled: 1
serializedVersion: 4
OutputAudioMixerGroup: {fileID: 0}
m_audioClip: {fileID: 0}
m_PlayOnAwake: 1
m_Volume: 1
m_Pitch: 1
Loop: 0
Mute: 0
Spatialize: 0
SpatializePostEffects: 0
Priority: 128
DopplerLevel: 1
MinDistance: 1
MaxDistance: 500
Pan2D: 0
rolloffMode: 0
BypassEffects: 0
BypassListenerEffects: 0
BypassReverbZones: 0
rolloffCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 1
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
panLevelCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 0
spreadCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 0
reverbZoneMixCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 0
--- !u!114 &4968772184202955189
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1014519456890440729}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3b05a64a5de3f8546bf586f42e37b979, type: 3}
m_Name:
m_EditorClassIdentifier:
_mediaPlayer: {fileID: 1047330333873833263}
_audioOutputMode: 1
_channelMask: -1
_supportPositionalAudio: 0
--- !u!114 &8186953721405597799
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1014519456890440729}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 448e5e4039505584c852da1a7cc5c361, type: 3}
m_Name:
m_EditorClassIdentifier:
_mediaPlayer: {fileID: 1047330333873833263}
_options:
applyHSBC: 1
hue: 0
saturation: 0.5
brightness: 0.5
contrast: 0.5
gamma: 1
tint: {r: 1, g: 1, b: 1, a: 1}
generateMipmaps: 0
aspectRatio: 5
_resolveFlags: 23
_externalTexture: {fileID: 0}
--- !u!114 &7213117712083895936
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1014519456890440729}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e7def708574c4f72a8cf1a83a4996f59, type: 3}
m_Name:
m_EditorClassIdentifier:
VideoIndex: 0
_mediaPlayer: {fileID: 1047330333873833263}
ResolveToRenderTexture: {fileID: 8186953721405597799}
NowRT: {fileID: 0}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: aaf1964f27ee49a4983d0d1e08c721ba
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -438,7 +438,6 @@ GameObject:
- component: {fileID: 318170204}
- component: {fileID: 318170203}
- component: {fileID: 318170205}
- component: {fileID: 318170206}
- component: {fileID: 318170207}
m_Layer: 0
m_Name: Init
@@ -486,21 +485,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: a228470747f546a19a430d3cea468862, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &318170206
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 318170202}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fb49b3d3fe4d41268789ab6546d8d824, type: 3}
m_Name:
m_EditorClassIdentifier:
_mediaPlayer: {fileID: 5471824021686675642}
ResolveToRenderTexture: {fileID: 8862102617388517826}
NowRT: {fileID: 0}
--- !u!114 &318170207
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -732,339 +716,7 @@ Transform:
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &2658711348446672123
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8192882270736362584}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3b05a64a5de3f8546bf586f42e37b979, type: 3}
m_Name:
m_EditorClassIdentifier:
_mediaPlayer: {fileID: 5471824021686675642}
_audioOutputMode: 1
_channelMask: -1
_supportPositionalAudio: 0
--- !u!114 &5471824021686675642
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8192882270736362584}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 638c870cac4da414fba921606d504407, type: 3}
m_Name:
m_EditorClassIdentifier:
_mediaSource: 1
_mediaReference: {fileID: 11400000, guid: 7b8a48f17a76b0d449f396690db75ebf, type: 2}
_mediaPath:
_pathType: 0
_path:
_fallbackMediaHints:
transparency: 0
alphaPacking: 0
stereoPacking: 0
_autoOpen: 1
_autoPlayOnStart: 0
_loop: 1
_audioVolume: 1
_audioBalance: 0
_audioMuted: 0
_playbackRate: 1
_useResampler: 0
_resampleMode: 0
_resampleBufferSize: 5
_videoMapping: 0
_textureFilterMode: 1
_textureWrapMode: 1
_textureAnisoLevel: 0
_sideloadSubtitles: 0
_subtitlePath:
_pathType: 2
_path:
_audioHeadTransform: {fileID: 0}
_audioFocusEnabled: 0
_audioFocusTransform: {fileID: 0}
_audioFocusWidthDegrees: 90
_audioFocusOffLevelDB: 0
_httpHeaders:
httpHeaders: []
_keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
_events:
m_PersistentCalls:
m_Calls: []
_eventMask: -1
_pauseMediaOnAppPause: 1
_playMediaOnAppUnpause: 1
_persistent: 0
_forceFileFormat: 0
_optionsWindows:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
videoApi: 0
useHardwareDecoding: 1
useRendererSync: 1
useTextureMips: 0
use10BitTextures: 0
hintAlphaChannel: 0
useLowLatency: 0
useCustomMovParser: 0
useHapNotchLC: 0
useStereoDetection: 1
useTextTrackSupport: 1
useFacebookAudio360Support: 1
useAudioDelay: 0
forceAudioOutputDeviceName:
preferredFilters: []
_audioMode: 0
audio360ChannelMode: 0
startWithHighestBitrate: 0
useLowLiveLatency: 0
parallelFrameCount: 3
prerollFrameCount: 4
useUnityAudio: 0
enableAudio360: 0
_options_macOS:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
textureFormat: 0
_audioMode: 0
_flags: 0
maximumPlaybackRate: 2
_preferredPeakBitRate: 0
_preferredPeakBitRateUnits: 1
_preferredForwardBufferDuration: 0
_preferredMaximumResolution: 0
_customPreferredMaximumResolution: {x: 0, y: 0}
_options_iOS:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
textureFormat: 0
_audioMode: 0
_flags: 0
maximumPlaybackRate: 2
_preferredPeakBitRate: 0
_preferredPeakBitRateUnits: 1
_preferredForwardBufferDuration: 0
_preferredMaximumResolution: 0
_customPreferredMaximumResolution: {x: 0, y: 0}
_options_tvOS:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
textureFormat: 0
_audioMode: 0
_flags: 0
maximumPlaybackRate: 2
_preferredPeakBitRate: 0
_preferredPeakBitRateUnits: 1
_preferredForwardBufferDuration: 0
_preferredMaximumResolution: 0
_customPreferredMaximumResolution: {x: 0, y: 0}
_options_visionOS:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
textureFormat: 0
_audioMode: 0
_flags: 0
maximumPlaybackRate: 2
_preferredPeakBitRate: 0
_preferredPeakBitRateUnits: 1
_preferredForwardBufferDuration: 0
_preferredMaximumResolution: 0
_customPreferredMaximumResolution: {x: 0, y: 0}
_optionsAndroid:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
videoOutputMode: 0
textureFormat: 0
_generateMipmaps: 0
_audioMode: 0
_preferredMaximumResolution: 3
_customPreferredMaximumResolution: {x: 0, y: 0}
_preferredPeakBitRate: 16
_preferredPeakBitRateUnits: 2
videoApi: 2
showPosterFrame: 0
audio360ChannelMode: 0
audio360LatencyMS: 0
preferSoftwareDecoder: 0
forceRtpTCP: 0
forceEnableMediaCodecAsynchronousQueueing: 0
allowUnsupportedVideoTrackVariants: 0
fileOffset: 0
startWithHighestBitrate: 1
minBufferMs: 10000
maxBufferMs: 50000
bufferForPlaybackMs: 1000
bufferForPlaybackAfterRebufferMs: 2000
prioritiseTimeOverSize: 0
useFastOesPath: 0
audioOutput: 0
blitTextureFiltering: 0
forceEnableMediaCodecAsyncQueueing: 0
enableAudio360: 0
_optionsOpenHarmony:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
textureFormat: 0
_generateMipmapsOH: 0
_useNormalizedOHMUrl: 1
_audioMode: 0
_preferredMaximumResolution: 0
_customPreferredMaximumResolution: {x: 0, y: 0}
_optionsWindowsUWP:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
useHardwareDecoding: 1
useRendererSync: 1
useTextureMips: 0
use10BitTextures: 0
hintOutput10Bit: 0
useLowLatency: 0
videoApi: 1
_audioMode: 0
audio360ChannelMode: 0
startWithHighestBitrate: 0
useLowLiveLatency: 0
_optionsWebGL:
httpHeaders:
httpHeaders: []
keyAuth:
keyServerToken:
overrideDecryptionKeyBase64:
externalLibrary: 0
useTextureMips: 0
_audioMode: 0
m_VideoPath:
m_VideoLocation: 2
--- !u!82 &6192315818390005783
AudioSource:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8192882270736362584}
m_Enabled: 1
serializedVersion: 4
OutputAudioMixerGroup: {fileID: 0}
m_audioClip: {fileID: 0}
m_PlayOnAwake: 1
m_Volume: 1
m_Pitch: 1
Loop: 0
Mute: 0
Spatialize: 0
SpatializePostEffects: 0
Priority: 128
DopplerLevel: 1
MinDistance: 1
MaxDistance: 500
Pan2D: 0
rolloffMode: 0
BypassEffects: 0
BypassListenerEffects: 0
BypassReverbZones: 0
rolloffCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 1
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
panLevelCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 0
spreadCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 0
reverbZoneMixCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 0
--- !u!1 &8192882270736362584
--- !u!1 &1389717445
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
@@ -1072,58 +724,43 @@ GameObject:
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8862102617388517825}
- component: {fileID: 5471824021686675642}
- component: {fileID: 6192315818390005783}
- component: {fileID: 2658711348446672123}
- component: {fileID: 8862102617388517826}
- component: {fileID: 1389717446}
- component: {fileID: 1389717447}
m_Layer: 0
m_Name: MediaPlayer
m_Name: MediaList
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &8862102617388517825
--- !u!4 &1389717446
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8192882270736362584}
m_GameObject: {fileID: 1389717445}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 657, y: 357, z: 0}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &8862102617388517826
--- !u!114 &1389717447
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8192882270736362584}
m_GameObject: {fileID: 1389717445}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 448e5e4039505584c852da1a7cc5c361, type: 3}
m_Script: {fileID: 11500000, guid: fb49b3d3fe4d41268789ab6546d8d824, type: 3}
m_Name:
m_EditorClassIdentifier:
_mediaPlayer: {fileID: 5471824021686675642}
_options:
applyHSBC: 1
hue: 0
saturation: 0.5
brightness: 0.5
contrast: 0.5
gamma: 1
tint: {r: 1, g: 1, b: 1, a: 1}
generateMipmaps: 0
aspectRatio: 5
_resolveFlags: 23
_externalTexture: {fileID: 0}
prefab: {fileID: 1014519456890440729, guid: aaf1964f27ee49a4983d0d1e08c721ba, type: 3}
--- !u!1660057539 &9223372036854775807
SceneRoots:
m_ObjectHideFlags: 0
@@ -1131,5 +768,5 @@ SceneRoots:
- {fileID: 519420032}
- {fileID: 619394802}
- {fileID: 318170204}
- {fileID: 8862102617388517825}
- {fileID: 101061951}
- {fileID: 1389717446}

View File

@@ -3,190 +3,225 @@ using System.Collections.Generic;
using NBC;
using RenderHeads.Media.AVProVideo;
using UnityEngine;
using UnityEngine.Serialization;
using Object = UnityEngine.Object;
namespace NBF
{
public class VideoManager : MonoBehaviour
{
[SerializeField] private MediaPlayer _mediaPlayer;
public static VideoManager Instance { get; private set; }
public ResolveToRenderTexture ResolveToRenderTexture;
public RenderTexture NowRT;
public Action<RenderTexture> OnPlayStart;
public Action<MediaPlayerEvent.EventType> OnHandleEvent;
private int _nowPlayUrlIndex = 0;
public float PlayProgress { get; private set; } = 0f;
private List<string> _urls = new List<string>()
{
"http://10.10.0.158:9888/files/video/1.mp4",
"http://10.10.0.158:9888/files/video/2.mp4",
"http://10.10.0.158:9888/files/video/3.mp4",
};
public GameObject prefab;
/// <summary>
/// 闲置的播放器
/// </summary>
private readonly Queue<VideoPlayerComponent> _idlePlayers = new Queue<VideoPlayerComponent>();
/// <summary>
/// 使用中的播放器
/// </summary>
private readonly List<VideoPlayerComponent> _usePlayers = new List<VideoPlayerComponent>();
private void Awake()
{
Instance = this;
_mediaPlayer.Events.AddListener(HandleEvent);
// Start adaptive stream using the highest resolution - ExoPlayer only
_mediaPlayer.PlatformOptionsAndroid.videoApi = Android.VideoApi.ExoPlayer;
_mediaPlayer.PlatformOptionsAndroid.startWithHighestBitrate = true;
// Set the maximum adaptive resolution to 1080p - ExoPlayer only
_mediaPlayer.PlatformOptionsAndroid.videoApi = Android.VideoApi.ExoPlayer;
_mediaPlayer.PlatformOptionsAndroid.preferredMaximumResolution =
MediaPlayer.OptionsAndroid.Resolution._1080p;
// // Set the peak adaptive bitrate to 4Mbps - ExoPlayer only
// _mediaPlayer.PlatformOptionsAndroid.videoApi = Android.VideoApi.ExoPlayer;
// _mediaPlayer.PlatformOptionsAndroid.preferredPeakBitRate = 4.0f;
// _mediaPlayer.PlatformOptionsAndroid.preferredPeakBitRateUnits =
// MediaPlayer.OptionsAndroid.BitRateUnits.Mbps;
}
private void Update()
/// <summary>
/// 获取一个播放器
/// </summary>
/// <returns></returns>
public VideoPlayerComponent GetPlayer(int videoIndex)
{
if (!_mediaPlayer) return;
if (_mediaPlayer.Info != null)
var ret = _usePlayers.Find(t => t.VideoIndex == videoIndex);
if (ret == null)
{
TimeRange timelineRange = GetTimelineRange();
double t = 0.0;
if (timelineRange.duration > 0.0)
{
t = ((_mediaPlayer.Control.GetCurrentTime() - timelineRange.startTime) / timelineRange.duration);
}
PlayProgress = Mathf.Clamp01((float)t);
var playerObject = Instantiate(prefab, transform);
ret = playerObject.GetComponent<VideoPlayerComponent>();
_usePlayers.Add(ret);
}
return ret;
}
#region
void HandleEvent(MediaPlayer mp, MediaPlayerEvent.EventType eventType, ErrorCode code)
/// <summary>
/// 返回一个播放器
/// </summary>
public void ReturnPlayer(int nowVideoIndex)
{
Debug.Log("MediaPlayer " + mp.name + " generated event: " + eventType.ToString());
OnHandleEvent?.Invoke(eventType);
if (eventType == MediaPlayerEvent.EventType.Error)
// _usePlayers.Remove(player);
// _idlePlayers.Enqueue(player);
List<VideoPlayerComponent> needRemove = new List<VideoPlayerComponent>();
foreach (var videoPlayerComponent in _usePlayers)
{
Debug.LogError("Error: " + code);
}
else if (eventType == MediaPlayerEvent.EventType.MetaDataReady)
{
Log.Info("播放数据已准备====");
}
else if (eventType == MediaPlayerEvent.EventType.Started)
{
var width = mp.Info.GetVideoWidth();
var height = mp.Info.GetVideoHeight();
Log.Info("播放开始====");
if (NowRT != null)
var offset = Math.Abs(videoPlayerComponent.VideoIndex - nowVideoIndex);
if (offset > 1)
{
NowRT.Release();
}
NowRT = new RenderTexture(width, height, 0, RenderTextureFormat.ARGB32);
ResolveToRenderTexture.ExternalTexture = NowRT;
OnPlayStart?.Invoke(NowRT);
}
}
#endregion
#region
public void TogglePlayPause()
{
if (_mediaPlayer && _mediaPlayer.Control != null)
{
if (_mediaPlayer.Control.IsPlaying())
{
Pause();
}
else
{
Play();
videoPlayerComponent.CloseMedia();
needRemove.Add(videoPlayerComponent);
}
}
}
public void Play()
{
if (_mediaPlayer && _mediaPlayer.Control != null)
foreach (var videoPlayerComponent in needRemove)
{
_mediaPlayer.Play();
#if UNITY_ANDROID || UNITY_OPENHARMONY
Screen.sleepTimeout = SleepTimeout.NeverSleep;
#endif
_usePlayers.Remove(videoPlayerComponent);
Destroy(videoPlayerComponent.gameObject);
}
}
private void Pause()
{
if (_mediaPlayer && _mediaPlayer.Control != null)
{
_mediaPlayer.Pause();
#if UNITY_ANDROID || UNITY_OPENHARMONY
Screen.sleepTimeout = SleepTimeout.SystemSetting;
#endif
}
}
#endregion
private TimeRange GetTimelineRange()
{
if (_mediaPlayer.Info != null)
{
return Helper.GetTimelineRange(_mediaPlayer.Info.GetDuration(),
_mediaPlayer.Control.GetSeekableTimes());
}
return new TimeRange();
}
public void Next()
{
if (_nowPlayUrlIndex >= _urls.Count - 1)
{
_nowPlayUrlIndex = 0;
}
else
{
_nowPlayUrlIndex++;
}
ChangeVideo();
}
public void Previous()
{
if (_nowPlayUrlIndex <= 0)
{
_nowPlayUrlIndex = _urls.Count - 1;
}
else
{
_nowPlayUrlIndex--;
}
ChangeVideo();
}
public void ChangeVideo()
{
_mediaPlayer.CloseMedia();
_mediaPlayer.SetMediaPath(new MediaPath(_urls[_nowPlayUrlIndex], MediaPathType.AbsolutePathOrURL));
_mediaPlayer.OpenMedia();
}
}
// {
// [SerializeField] private MediaPlayer _mediaPlayer;
//
// public static VideoManager Instance { get; private set; }
//
// public ResolveToRenderTexture ResolveToRenderTexture;
//
// public RenderTexture NowRT;
//
// public Action<RenderTexture> OnPlayStart;
// public Action<MediaPlayerEvent.EventType> OnHandleEvent;
//
// public float PlayProgress { get; private set; } = 0f;
//
//
// public bool IsPlaying =>
// _mediaPlayer != null && _mediaPlayer.Control != null && _mediaPlayer.Control.IsPlaying();
//
// private void Awake()
// {
// Instance = this;
//
// DontDestroyOnLoad(gameObject);
//
// _mediaPlayer.Events.AddListener(HandleEvent);
//
// // Start adaptive stream using the highest resolution - ExoPlayer only
// _mediaPlayer.PlatformOptionsAndroid.videoApi = Android.VideoApi.ExoPlayer;
// _mediaPlayer.PlatformOptionsAndroid.startWithHighestBitrate = true;
//
// // Set the maximum adaptive resolution to 1080p - ExoPlayer only
// _mediaPlayer.PlatformOptionsAndroid.videoApi = Android.VideoApi.ExoPlayer;
// _mediaPlayer.PlatformOptionsAndroid.preferredMaximumResolution =
// MediaPlayer.OptionsAndroid.Resolution._1080p;
// }
//
// private void Update()
// {
// if (!_mediaPlayer) return;
//
// if (_mediaPlayer.Info != null)
// {
// TimeRange timelineRange = GetTimelineRange();
// double t = 0.0;
// if (timelineRange.duration > 0.0)
// {
// t = ((_mediaPlayer.Control.GetCurrentTime() - timelineRange.startTime) / timelineRange.duration);
// }
//
// PlayProgress = Mathf.Clamp01((float)t);
// }
// }
//
// #region 事件
//
// void HandleEvent(MediaPlayer mp, MediaPlayerEvent.EventType eventType, ErrorCode code)
// {
// Debug.Log("MediaPlayer " + mp.name + " generated event: " + eventType.ToString());
// OnHandleEvent?.Invoke(eventType);
// if (eventType == MediaPlayerEvent.EventType.Error)
// {
// Debug.LogError("Error: " + code);
// }
// else if (eventType == MediaPlayerEvent.EventType.MetaDataReady)
// {
// Log.Info("播放数据已准备====");
// }
// else if (eventType == MediaPlayerEvent.EventType.Started)
// {
// var width = mp.Info.GetVideoWidth();
// var height = mp.Info.GetVideoHeight();
// Log.Info("播放开始====");
// if (NowRT != null)
// {
// NowRT.Release();
// }
//
// NowRT = new RenderTexture(width, height, 0, RenderTextureFormat.ARGB32);
//
// ResolveToRenderTexture.ExternalTexture = NowRT;
// OnPlayStart?.Invoke(NowRT);
// }
// }
//
// #endregion
//
// #region 播放控制
//
// public void TogglePlayPause()
// {
// if (_mediaPlayer && _mediaPlayer.Control != null)
// {
// if (_mediaPlayer.Control.IsPlaying())
// {
// Pause();
// }
// else
// {
// Play();
// }
// }
// }
//
// public void Play()
// {
// if (_mediaPlayer && _mediaPlayer.Control != null)
// {
// _mediaPlayer.Play();
//
// #if UNITY_ANDROID || UNITY_OPENHARMONY
// Screen.sleepTimeout = SleepTimeout.NeverSleep;
// #endif
// }
// }
//
// public void Pause()
// {
// if (_mediaPlayer && _mediaPlayer.Control != null)
// {
// _mediaPlayer.Pause();
// #if UNITY_ANDROID || UNITY_OPENHARMONY
// Screen.sleepTimeout = SleepTimeout.SystemSetting;
// #endif
// }
// }
//
// #endregion
//
//
// private TimeRange GetTimelineRange()
// {
// if (_mediaPlayer.Info != null)
// {
// return Helper.GetTimelineRange(_mediaPlayer.Info.GetDuration(),
// _mediaPlayer.Control.GetSeekableTimes());
// }
//
// return new TimeRange();
// }
//
//
// public void ChangeVideo(string url)
// {
// _mediaPlayer.CloseMedia();
// _mediaPlayer.SetMediaPath(new MediaPath(url, MediaPathType.AbsolutePathOrURL));
// _mediaPlayer.OpenMedia();
// }
// }
}

View File

@@ -0,0 +1,181 @@
using System;
using NBC;
using RenderHeads.Media.AVProVideo;
using UnityEngine;
namespace NBF
{
public class VideoPlayerComponent : MonoBehaviour
{
public int VideoIndex;
[SerializeField] private MediaPlayer _mediaPlayer;
public ResolveToRenderTexture ResolveToRenderTexture;
public RenderTexture NowRT;
public Action<RenderTexture> OnPlayStart;
public Action<MediaPlayerEvent.EventType> OnHandleEvent;
public float PlayProgress { get; private set; } = 0f;
public bool IsPlaying =>
_mediaPlayer != null && _mediaPlayer.Control != null && _mediaPlayer.Control.IsPlaying();
private void Awake()
{
_mediaPlayer.Events.AddListener(HandleEvent);
// Start adaptive stream using the highest resolution - ExoPlayer only
_mediaPlayer.PlatformOptionsAndroid.videoApi = Android.VideoApi.ExoPlayer;
_mediaPlayer.PlatformOptionsAndroid.startWithHighestBitrate = true;
// Set the maximum adaptive resolution to 1080p - ExoPlayer only
_mediaPlayer.PlatformOptionsAndroid.videoApi = Android.VideoApi.ExoPlayer;
_mediaPlayer.PlatformOptionsAndroid.preferredMaximumResolution =
MediaPlayer.OptionsAndroid.Resolution._1080p;
NowRT = new RenderTexture(1080, 1920, 0, RenderTextureFormat.ARGB32);
}
private void Update()
{
if (!_mediaPlayer) return;
if (_mediaPlayer.Info != null)
{
TimeRange timelineRange = GetTimelineRange();
double t = 0.0;
if (timelineRange.duration > 0.0)
{
t = ((_mediaPlayer.Control.GetCurrentTime() - timelineRange.startTime) / timelineRange.duration);
}
PlayProgress = Mathf.Clamp01((float)t);
}
}
#region
void HandleEvent(MediaPlayer mp, MediaPlayerEvent.EventType eventType, ErrorCode code)
{
Debug.Log("MediaPlayer " + mp.name + " generated event: " + eventType.ToString());
OnHandleEvent?.Invoke(eventType);
if (eventType == MediaPlayerEvent.EventType.Error)
{
Debug.LogError("Error: " + code);
}
else if (eventType == MediaPlayerEvent.EventType.MetaDataReady)
{
Log.Info("播放数据已准备====");
}
else if (eventType == MediaPlayerEvent.EventType.ReadyToPlay)
{
Log.Info("播放数据已准备====");
}
else if (eventType == MediaPlayerEvent.EventType.Started)
{
Log.Info("播放开始====");
var width = mp.Info.GetVideoWidth();
var height = mp.Info.GetVideoHeight();
NowRT.width = width;
NowRT.height = height;
ResolveToRenderTexture.ExternalTexture = NowRT;
OnPlayStart?.Invoke(NowRT);
}
}
#endregion
#region
public void TogglePlayPause()
{
if (_mediaPlayer && _mediaPlayer.Control != null)
{
if (_mediaPlayer.Control.IsPlaying())
{
Pause();
}
else
{
Play();
}
}
}
public void Play()
{
if (_mediaPlayer && _mediaPlayer.Control != null)
{
_mediaPlayer.Play();
#if UNITY_ANDROID || UNITY_OPENHARMONY
Screen.sleepTimeout = SleepTimeout.NeverSleep;
#endif
}
}
public void Pause()
{
if (_mediaPlayer && _mediaPlayer.Control != null)
{
_mediaPlayer.Pause();
#if UNITY_ANDROID || UNITY_OPENHARMONY
Screen.sleepTimeout = SleepTimeout.SystemSetting;
#endif
}
}
#endregion
private TimeRange GetTimelineRange()
{
if (_mediaPlayer.Info != null)
{
return Helper.GetTimelineRange(_mediaPlayer.Info.GetDuration(),
_mediaPlayer.Control.GetSeekableTimes());
}
return new TimeRange();
}
public void ChangeVideo(string url, bool isAutoPlay)
{
if (isAutoPlay)
{
_mediaPlayer.AudioVolume = 1;
}
else
{
_mediaPlayer.AudioVolume = 0;
}
if (_mediaPlayer.MediaPath != null && !_mediaPlayer.MediaPath.Path.Equals(url))
{
_mediaPlayer.CloseMedia();
_mediaPlayer.SetMediaPath(new MediaPath(url, MediaPathType.AbsolutePathOrURL));
_mediaPlayer.OpenMedia(isAutoPlay);
}
else if (isAutoPlay)
{
_mediaPlayer.Play();
}
else
{
_mediaPlayer.Stop();
}
}
public void CloseMedia()
{
_mediaPlayer.Stop();
_mediaPlayer.CloseMedia();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e7def708574c4f72a8cf1a83a4996f59
timeCreated: 1770816309

View File

@@ -1,7 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NBC;
using RenderHeads.Media.AVProVideo;
using UnityEngine;
using UnityEngine.Networking;
namespace NBF
{
@@ -9,45 +12,314 @@ namespace NBF
{
public static Game Instance { get; private set; }
public readonly List<VideoRetData> Videos = new List<VideoRetData>();
public int Page = 1;
public int PageSize = 100;
private void Awake()
{
Instance = this;
}
public void Tick(Action<bool> callback = null)
private void Start()
{
var dic = new Dictionary<string, string>
{
{ "device", PlatformInfo.GetAndroidID() },
{ "deviceName", "android" },
{ "id", "0" },
{ "time", "0" }
};
Net.Instance.Send("/api/device", dic, result => { callback?.Invoke(result.Code == 0); });
Net.Instance.OnError += OnNetError;
}
public void GetList(Action callback)
private void OnDestroy()
{
Net.Instance.OnError -= OnNetError;
}
private void OnNetError(UnityWebRequest.Result result, string msg)
{
if (result == UnityWebRequest.Result.ConnectionError)
{
// VideoManager.Instance.Pause();
var panel = UI.Inst.GetUI<PlayerPanel>();
if (panel != null && panel.IsShowing)
{
LoginPanel.Show();
PlayerPanel.Hide();
}
}
}
#region
private readonly List<VideoRetData> Videos = new List<VideoRetData>();
private bool _isLastPage = false;
public int Page = 0;
public const int PageSize = 5;
private Action OnPreLoadNextData;
public VideoRetData GetVideoDataByIndex(int index)
{
if (index < 0 || index >= Videos.Count) return null;
if (index >= Videos.Count - 2) //如果再获取倒数3个则需要预加载后续资源
{
//需要预加载了
PreLoadNextData();
}
return Videos[index];
}
public void PreLoadNextData(Action callback = null)
{
OnPreLoadNextData = callback;
GetList(Page + 1);
}
public bool IsLastVideo(int index)
{
return index == Videos.Count - 1;
}
private void GetList(int page)
{
if (page < 1) return;
var dic = new Dictionary<string, string>
{
{ "page", Page.ToString() },
{ "page", page.ToString() },
{ "PageSize", PageSize.ToString() }
};
Net.Instance.Send("/api/list", dic, result =>
{
ParseVideo(result);
callback?.Invoke();
});
Net.Instance.Send("/api/list", dic, ParseVideo);
}
private void ParseVideo(HttpResult httpResult)
{
if (httpResult.Code != 0) return;
var retData = httpResult.Data.ToObject<PageListData<VideoRetData>>();
if (retData != null)
{
if (retData.List.Count > 0)
{
Videos.AddRange(retData.List);
_isLastPage = false;
}
if (retData.Page > Page && retData.List.Count < 1)
{
_isLastPage = true;
}
Page = retData.Page;
}
OnPreLoadNextData?.Invoke();
}
#endregion
// #region 视频数据
//
// private int _page = 1;
// private const int PageSize = 4;
//
// private readonly SortedList<int, VideoRetData> Videos = new();
// public int CurrentVideoId = 0;
//
// // private readonly Queue<Action<VideoRetData>> _actions = new Queue<Action<VideoRetData>>();
//
// private Action<VideoRetData> _action;
// private int _lastNextValue = 0;
//
// public void GetVideoData(int next, Action<VideoRetData> callback)
// {
// if (Videos.Count == 0)
// {
// callback?.Invoke(null);
// GetList(_page);
// return;
// }
//
// _lastNextValue = next;
// _action = callback;
// if (CurrentVideoId == 0)
// {
// GetVideoDataConfirm(GetFirstVideo());
// }
// else
// {
// if (next > 0)
// {
// GetVideoDataConfirm(GetNextVideo());
// }
// else if (next < 0)
// {
// GetVideoDataConfirm(GetPreviousVideo());
// }
// else
// {
// //获取当前
// GetVideoDataConfirm(GetCurrentVideo());
// }
// }
// }
//
// public void GetVideoDataConfirm(VideoRetData videoRetData)
// {
// _action?.Invoke(videoRetData);
// _action = null;
// if (videoRetData == null)
// {
// return;
// }
//
//
// CurrentVideoId = videoRetData.Id;
//
// if (_lastNextValue > 0)
// {
// //最后一次操作是获取下一个,
// if (IsLastVideo())
// {
// //获取下一页
// GetList(_page + 1);
// }
// }
// else
// {
// //最后一次操作是获取上一个,
// if (IsLastVideo())
// {
// //获取上一页
// GetList(_page - 1);
// }
// }
// }
//
//
// private void GetList(int page)
// {
// if (page < 1) return;
// var dic = new Dictionary<string, string>
// {
// { "page", page.ToString() },
// { "PageSize", PageSize.ToString() }
// };
// Net.Instance.Send("/api/list", dic, ParseVideo);
// }
//
// private void ParseVideo(HttpResult httpResult)
// {
// if (httpResult.Code != 0) return;
// var retData = httpResult.Data.ToObject<PageListData<VideoRetData>>();
// if (retData != null && retData.List.Count > 0)
// {
// _page = retData.Page;
// AddVideos(retData.List);
// }
// }
//
//
// #region 视频数据获取
//
// /// <summary>
// /// 添加视频
// /// </summary>
// /// <param name="videoList"></param>
// private void AddVideos(IEnumerable<VideoRetData> videoList)
// {
// foreach (var video in videoList)
// {
// Videos.TryAdd(video.Id, video);
// }
// }
//
// /// <summary>
// /// 获取下一个视频
// /// </summary>
// /// <returns></returns>
// private VideoRetData GetNextVideo()
// {
// int currentIndex = Videos.IndexOfKey(CurrentVideoId);
//
// if (currentIndex >= 0 && currentIndex < Videos.Count - 1)
// {
// var nextVideo = Videos.Values[currentIndex + 1];
// CurrentVideoId = nextVideo.Id;
// return nextVideo;
// }
//
// return null;
// }
//
// /// <summary>
// /// 获取上一个视频
// /// </summary>
// /// <returns></returns>
// public VideoRetData GetPreviousVideo()
// {
// int currentIndex = Videos.IndexOfKey(CurrentVideoId);
//
// if (currentIndex > 0)
// {
// var prevVideo = Videos.Values[currentIndex - 1];
// CurrentVideoId = prevVideo.Id;
// return prevVideo;
// }
//
// return null;
// }
//
// /// <summary>
// /// 获取第一个视频
// /// </summary>
// /// <returns></returns>
// private VideoRetData GetFirstVideo()
// {
// if (Videos.Count > 0)
// {
// var video = Videos.Values[0];
// CurrentVideoId = video.Id;
// return video;
// }
//
// return null;
// }
//
// /// <summary>
// /// 获取最后一个视频
// /// </summary>
// /// <returns></returns>
// private VideoRetData GetLastVideo()
// {
// if (Videos.Count > 0)
// {
// var video = Videos.Values[^1];
// CurrentVideoId = video.Id;
// return video;
// }
//
// return null;
// }
//
//
// /// <summary>
// /// 获取当前视频
// /// </summary>
// /// <returns></returns>
// private VideoRetData GetCurrentVideo()
// {
// return Videos.GetValueOrDefault(CurrentVideoId);
// }
//
// // 判断是否是第一个视频
// public bool IsFirstVideo()
// {
// if (Videos.Count == 0) return false;
// return Videos.Keys[0] == CurrentVideoId;
// }
//
// // 判断是否是最后一个视频
// public bool IsLastVideo()
// {
// if (Videos.Count == 0) return false;
// return Videos.Keys[^1] == CurrentVideoId;
// }
//
// #endregion
//
// #endregion
}
}

View File

@@ -24,5 +24,9 @@ namespace NBF
public int Share { get; set; }
public int Collect { get; set; }
public string AuthorName { get; set; }
/// <summary>
/// 所处的页
/// </summary>
public int Page { get; set; }
}
}

View File

@@ -16,19 +16,44 @@ namespace NBF
public JToken Data { get; set; }
}
class NetData
{
public string action;
public Dictionary<string, string> form;
public Action<HttpResult> callback = null;
public bool Success = false;
public void Send()
{
}
}
public class Net : MonoBehaviour
{
private string serverUrl = "http://localhost:8080";
public string ServerUrl { get; private set; } = "http://localhost:8080";
private string serverPassword = "";
public static Net Instance { get; private set; }
public event Action<UnityWebRequest.Result, string> OnError;
private string DeviceId;
private string DeviceName;
Queue<NetData> _netDataQueue = new Queue<NetData>();
private void Awake()
{
Instance = this;
}
private void Start()
{
DeviceId = PlatformInfo.GetAndroidID();
DeviceName = PlatformInfo.GetDeviceModel();
}
public void SetServer(string server, string password)
{
if (!(server.StartsWith("http://") || server.StartsWith("https://")))
@@ -45,11 +70,24 @@ namespace NBF
server = server.Substring(0, server.Length - 1);
}
serverUrl = server;
ServerUrl = server;
serverPassword = password;
}
public void Tick(int id, int time, int count, Action<HttpResult> callback = null)
{
var dic = new Dictionary<string, string>
{
{ "device", DeviceId },
{ "deviceName", DeviceName },
{ "id", id.ToString() },
{ "time", time.ToString() },
{ "watchCount", count.ToString() }
};
Send("/api/tick", dic, callback);
}
#region Post
public void Send(string action, Dictionary<string, string> form, Action<HttpResult> callback = null)
@@ -65,11 +103,11 @@ namespace NBF
form = new Dictionary<string, string>();
}
var url = serverUrl + action;
var url = ServerUrl + action;
form["sign"] = serverPassword;
UnityWebRequest request = UnityWebRequest.Post(url, form);
request.downloadHandler = new DownloadHandlerBuffer();
Debug.Log("Request: " + JsonConvert.SerializeObject(form));
// 4⃣ 发送
yield return request.SendWebRequest();
@@ -83,6 +121,7 @@ namespace NBF
Code = -1,
Data = request.error
});
OnError?.Invoke(request.result, request.error);
}
else
{

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 438abb1f3b6d4cc0b53b38e4a3ce2dca
timeCreated: 1770893968

View File

@@ -0,0 +1,27 @@
/**本脚本为自动生成每次生成会覆盖请勿手动修改生成插件文档及项目地址https://git.whoot.com/whoot-games/whoot.fguieditorplugin**/
using FairyGUI;
using FairyGUI.Utils;
using NBC;
namespace NBF
{
public partial class VideoEditorItem
{
public const string URL = "ui://hxr7rc7pxjb91hr";
public GButton BtnEdit;
public GButton BtnDelete;
public override void ConstructFromXML(XML xml)
{
base.ConstructFromXML(xml);
BtnEdit = (GButton)GetChild("BtnEdit");
BtnDelete = (GButton)GetChild("BtnDelete");
OnInited();
UILanguage.TrySetComponentLanguage(this);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 099e24366cdaca745a18241b7f4433f3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,27 @@
// 本脚本只在不存在时会生成一次。组件逻辑写在当前脚本内。已存在不会再次生成覆盖
using UnityEngine;
using FairyGUI;
using NBC;
namespace NBF
{
public partial class VideoEditorItem : GButton
{
private VideoRetData _video;
private void OnInited()
{
BtnDelete.onClick.Set(OnBtnDelete);
}
public void InitData(VideoRetData videoRetData)
{
_video = videoRetData;
}
private void OnBtnDelete()
{
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9084f28041b341548a5902db8e6f8fce
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,44 @@
/**本脚本为自动生成每次生成会覆盖请勿手动修改生成插件文档及项目地址https://git.whoot.com/whoot-games/whoot.fguieditorplugin**/
using FairyGUI;
using FairyGUI.Utils;
using NBC;
using System.Collections.Generic;
namespace NBF
{
/// <summary> </summary>
public partial class VideoEditorPanel
{
public GObject this[string aKey] => ContentPane.GetChild(aKey);
public override string UIPackName => "Main";
public override string UIResName => "VideoEditorPanel";
[AutoFind(Name = "page")]
public Controller page;
[AutoFind(Name = "List")]
public VideoListPage List;
[AutoFind(Name = "Nav")]
public GLabel Nav;
[AutoFind(Name = "BtnStatistics")]
public GButton BtnStatistics;
[AutoFind(Name = "BtnVideoList")]
public GButton BtnVideoList;
[AutoFind(Name = "BtnAdd")]
public GButton BtnAdd;
[AutoFind(Name = "BtnDevice")]
public GButton BtnDevice;
[AutoFind(Name = "BtnAdmin")]
public GButton BtnAdmin;
[AutoFind(Name = "MenuGroup")]
public GGroup MenuGroup;
public override string[] GetDependPackages(){ return new string[] {}; }
public static void Show(object param = null){ UI.Inst.OpenUI<VideoEditorPanel>(param); }
public static void Hide(){ UI.Inst.HideUI<VideoEditorPanel>(); }
public static void Del(){ UI.Inst.DestroyUI<VideoEditorPanel>(); }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 27be91422465e4b47931adc9c17d8585
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
// 本脚本只在不存在时会生成一次。已存在不会再次生成覆盖
using UnityEngine;
using NBC;
namespace NBF
{
public partial class VideoEditorPanel : UIPanel
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 768e9416eb4a9a74c894f1244463d0e6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,25 @@
/**本脚本为自动生成每次生成会覆盖请勿手动修改生成插件文档及项目地址https://git.whoot.com/whoot-games/whoot.fguieditorplugin**/
using FairyGUI;
using FairyGUI.Utils;
using NBC;
namespace NBF
{
public partial class VideoListPage
{
public const string URL = "ui://hxr7rc7pxjb91hz";
public GList List;
public override void ConstructFromXML(XML xml)
{
base.ConstructFromXML(xml);
List = (GList)GetChild("List");
OnInited();
UILanguage.TrySetComponentLanguage(this);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 82bf9bcc224708147b555ad12a9f8536
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,97 @@
// 本脚本只在不存在时会生成一次。组件逻辑写在当前脚本内。已存在不会再次生成覆盖
using System.Collections.Generic;
using UnityEngine;
using FairyGUI;
using NBC;
namespace NBF
{
public partial class VideoListPage : GComponent
{
public const int PageSize = 20;
private readonly List<VideoRetData> Videos = new List<VideoRetData>();
private GComponent _footer;
private Controller _controller;
public int Page = 0;
private void OnInited()
{
List.itemRenderer = RenderListItem1;
List.SetVirtual();
List.scrollPane.onPullUpRelease.Add(OnPullUpToRefresh);
_footer = (GComponent)List.scrollPane.footer;
_controller = _footer.GetController("style");
}
private void SetList()
{
List.numItems = Videos.Count;
}
void RenderListItem1(int index, GObject obj)
{
if (obj is VideoEditorItem item)
{
}
// GButton item = obj.asButton;
// item.title = "Item " + (_list1.numItems - index - 1);
}
void OnPullUpToRefresh()
{
_controller.selectedIndex = 1;
List.scrollPane.LockFooter(_footer.sourceHeight);
GetList(Page + 1);
// //Simulate a async resquest
// Timers.inst.Add(2, 1, (object param) =>
// {
// List.numItems += 5;
//
// //Refresh completed
// _controller.selectedIndex = 0;
// List.scrollPane.LockFooter(0);
// });
}
#region
private void GetList(int page)
{
if (page < 1) return;
var dic = new Dictionary<string, string>
{
{ "page", page.ToString() },
{ "PageSize", PageSize.ToString() }
};
Net.Instance.Send("/api/list", dic, ParseVideo);
}
private void ParseVideo(HttpResult httpResult)
{
_controller.selectedIndex = 0;
List.scrollPane.LockFooter(0);
if (httpResult.Code == 0)
{
var retData = httpResult.Data.ToObject<PageListData<VideoRetData>>();
if (retData != null)
{
if (retData.List.Count > 0)
{
Videos.AddRange(retData.List);
}
Page = retData.Page;
}
}
SetList();
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f48b7c83438fa874f835afb8a9adf58f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -12,6 +12,7 @@ namespace NBF
{
private string serverUrl;
private string serverPassword;
private bool autoLogin = true;
protected override void OnInit()
{
@@ -29,7 +30,7 @@ namespace NBF
InputPass.Input.text = serverPassword;
if (!string.IsNullOrEmpty(serverUrl) && !string.IsNullOrEmpty(serverPassword))
{
Connect();
if (autoLogin) Connect();
}
}
@@ -62,12 +63,16 @@ namespace NBF
PlayerPrefs.SetString("serverUrl", serverUrl);
PlayerPrefs.SetString("serverPassword", serverPassword);
Game.Instance.Tick((ret) =>
// PlayerPanel.Show();
autoLogin = false;
Net.Instance.Tick(0, 0, 0, (ret) =>
{
if (ret)
if (ret.Code == 0)
{
PlayerPanel.Show();
// PlayerPanel.Show();
VideoEditorPanel.Show();
}
else
{

View File

@@ -10,8 +10,11 @@ namespace NBF
public static void BindAll()
{
UIObjectFactory.SetPackageItemExtension(CommonInput.URL, typeof(CommonInput));
UIObjectFactory.SetPackageItemExtension(PlayRightGroup.URL, typeof(PlayRightGroup));
UIObjectFactory.SetPackageItemExtension(PlayerBottomInfo.URL, typeof(PlayerBottomInfo));
UIObjectFactory.SetPackageItemExtension(VideoPlayer.URL, typeof(VideoPlayer));
UIObjectFactory.SetPackageItemExtension(VideoEditorItem.URL, typeof(VideoEditorItem));
UIObjectFactory.SetPackageItemExtension(VideoListPage.URL, typeof(VideoListPage));
}
}
}

View File

@@ -0,0 +1,33 @@
/**本脚本为自动生成每次生成会覆盖请勿手动修改生成插件文档及项目地址https://git.whoot.com/whoot-games/whoot.fguieditorplugin**/
using FairyGUI;
using FairyGUI.Utils;
using NBC;
namespace NBF
{
public partial class PlayRightGroup
{
public const string URL = "ui://hxr7rc7pt33p1h6";
public GComponent Head;
public GButton BtnLike;
public GButton BtnMessage;
public GButton BtnCollect;
public GButton BtnShare;
public override void ConstructFromXML(XML xml)
{
base.ConstructFromXML(xml);
Head = (GComponent)GetChild("Head");
BtnLike = (GButton)GetChild("BtnLike");
BtnMessage = (GButton)GetChild("BtnMessage");
BtnCollect = (GButton)GetChild("BtnCollect");
BtnShare = (GButton)GetChild("BtnShare");
OnInited();
UILanguage.TrySetComponentLanguage(this);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4dc0689bc069b2543be2ec2fb3b217a2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
// 本脚本只在不存在时会生成一次。组件逻辑写在当前脚本内。已存在不会再次生成覆盖
using UnityEngine;
using FairyGUI;
using NBC;
namespace NBF
{
public partial class PlayRightGroup : GComponent
{
private void OnInited()
{
}
public void SetData(VideoRetData videoRetData)
{
BtnLike.title = videoRetData.Like.FormatNumber();
BtnCollect.title = videoRetData.Collect.FormatNumber();
BtnMessage.title = videoRetData.Message.FormatNumber();
BtnShare.title = videoRetData.Share.FormatNumber();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ad974c2bb232b2a428c282c4333372a4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -11,5 +11,11 @@ namespace NBF
private void OnInited()
{
}
public void SetData(VideoRetData videoRetData)
{
TextName.text = $"@{videoRetData.AuthorName}";
TextDesc.text = $"@{videoRetData.Title}{videoRetData.Desc}";
}
}
}

View File

@@ -14,20 +14,20 @@ namespace NBF
public override string UIPackName => "Main";
public override string UIResName => "PlayerPanel";
[AutoFind(Name = "stageCtrl")]
public Controller stageCtrl;
[AutoFind(Name = "PlayBack")]
public GGraph PlayBack;
[AutoFind(Name = "Video")]
public VideoPlayer Video;
[AutoFind(Name = "VideoMask")]
public GGraph VideoMask;
[AutoFind(Name = "bottomBack")]
public GGraph bottomBack;
[AutoFind(Name = "BtnNext")]
public GButton BtnNext;
[AutoFind(Name = "BtnPrev")]
public GButton BtnPrev;
[AutoFind(Name = "VideoTop")]
public VideoPlayer VideoTop;
[AutoFind(Name = "Video")]
public VideoPlayer Video;
[AutoFind(Name = "VideoBottom")]
public VideoPlayer VideoBottom;
[AutoFind(Name = "Progress")]
public GProgressBar Progress;
[AutoFind(Name = "BtnPause")]
public GComponent BtnPause;
public override string[] GetDependPackages(){ return new string[] {}; }
public static void Show(object param = null){ UI.Inst.OpenUI<PlayerPanel>(param); }

View File

@@ -1,5 +1,7 @@
// 本脚本只在不存在时会生成一次。已存在不会再次生成覆盖
using System;
using System.Collections.Generic;
using FairyGUI;
using UnityEngine;
using NBC;
@@ -16,45 +18,138 @@ namespace NBF
this.AutoAddClick(OnClick);
TryGetTime = 5;
Progress.max = 1;
GetVideoData();
stageCtrl.selectedIndex = 0;
}
private void GetVideoData()
protected override void OnInit()
{
Game.Instance.GetList(OnGetList);
SwipeGesture gesture = new SwipeGesture(BtnPause);
gesture.onBegin.Set(OnSwipeBegin);
gesture.onMove.Set(OnSwipeMove);
gesture.onEnd.Set(OnSwipeEnd);
gesture.onAction.Add(OnSwipeGesture);
Game.Instance.PreLoadNextData(Nmsl);
// ResetPlayerPos();
}
private void OnGetList()
private void Nmsl()
{
if (Game.Instance.Videos.Count > 0)
Play(0);
}
#region UI组件管理
// private void ResetPlayerPos()
// {
// for (int i = 0; i < _videoPlayers.Count; i++)
// {
// var player = _videoPlayers[i];
// player.y = BtnPause.height * (i - 1);
// player.x = 0;
// player.size = BtnPause.size;
// }
// }
#endregion
#region
// private int _tryTime = 1;
// private int _lastPlayValue;
private int _nowIndex = 0;
public void Play(int value = 0)
{
var nowIndex = _nowIndex + value;
VideoTop.PlayVideo(nowIndex - 1, VideoPlayMode.Top);
VideoBottom.PlayVideo(nowIndex + 1, VideoPlayMode.Bottom);
Video.PlayVideo(nowIndex, VideoPlayMode.Mid);
_nowIndex = nowIndex;
Video.height = BtnPause.height;
VideoTop.height = BtnPause.height;
VideoBottom.height = BtnPause.height;
VideoManager.Instance.ReturnPlayer(_nowIndex);
}
#endregion
#region
private float _defY = 0;
private float _offsetValue;
private void OnSwipeBegin(EventContext context)
{
_offsetValue = 0;
}
private void OnSwipeMove(EventContext context)
{
// if (IsLoading) return;
var gesture = context.sender as SwipeGesture;
if (gesture == null) return;
_offsetValue += gesture.delta.y;
if (_nowIndex == 0 && _offsetValue > 0)
{
stageCtrl.selectedIndex = 1;
return; // 第一个不允许滑动至上一个
}
else
Video.y = _defY + _offsetValue;
}
private void OnSwipeEnd(EventContext context)
{
Video.y = _defY;
}
private void OnSwipeGesture(EventContext context)
{
// if (IsLoading) return;
SwipeGesture swipeGesture = (SwipeGesture)context.sender;
var value = Math.Abs(_offsetValue);
if (value < 300)
{
Notices.Show($"没有视频数据!{TryGetTime}秒后重试");
Timer.Once(TryGetTime, this, GetVideoData);
TryGetTime *= 2;
return;
}
if (swipeGesture.position.y < 0) //向上滑动
{
Log.Info($"向上滑动 切换下一个视频 _offsetValue={_offsetValue} y={swipeGesture.position.y}");
if (Game.Instance.IsLastVideo(_nowIndex))
{
Game.Instance.PreLoadNextData();
return;
}
Play(1);
}
else if (_nowIndex > 0)
{
Log.Info($"向下滑动 切换上一个视频 _offsetValue={_offsetValue} y={swipeGesture.position.y}");
Play(-1);
}
}
#endregion
protected override void OnUpdate()
{
base.OnUpdate();
Progress.value = VideoManager.Instance.PlayProgress;
// Progress.value = VideoManager.Instance.PlayProgress;
}
private void OnClick(GComponent btn)
{
if (btn == BtnNext)
{
VideoManager.Instance.Next();
}
else if (btn == BtnPrev)
{
VideoManager.Instance.Previous();
}
// if (btn == BtnNext)
// {
// // VideoManager.Instance.Next();
// }
// else if (btn == BtnPrev)
// {
// // VideoManager.Instance.Previous();
// }
}
}
}

View File

@@ -22,8 +22,6 @@ namespace NBF
Add("ui://hxr7rc7pfhdrzd", new UIComponentLanguage()
{
{ "n12_t33p", "请输入账号" },
{ "n13_t33p", "请输入密码" },
{ "n10_t33p", "请输入服务器地址" },
}
);

View File

@@ -12,9 +12,12 @@ namespace NBF
public const string URL = "ui://hxr7rc7pt33p1hg";
public Controller pauseCtrl;
public Controller stageCtrl;
public GGraph PlayBack;
public GLoader VideoVer;
public GComponent BtnPause;
public PlayerBottomInfo BottomInfo;
public PlayRightGroup LeftInfo;
public Transition pause;
public Transition play;
public Transition StartedAnim;
@@ -24,9 +27,12 @@ namespace NBF
base.ConstructFromXML(xml);
pauseCtrl = GetController("pauseCtrl");
stageCtrl = GetController("stageCtrl");
PlayBack = (GGraph)GetChild("PlayBack");
VideoVer = (GLoader)GetChild("VideoVer");
BtnPause = (GComponent)GetChild("BtnPause");
BottomInfo = (PlayerBottomInfo)GetChild("BottomInfo");
LeftInfo = (PlayRightGroup)GetChild("LeftInfo");
pause = GetTransition("pause");
play = GetTransition("play");
StartedAnim = GetTransition("StartedAnim");

View File

@@ -1,130 +1,188 @@
// 本脚本只在不存在时会生成一次。组件逻辑写在当前脚本内。已存在不会再次生成覆盖
using System;
using UnityEngine;
using FairyGUI;
using NBC;
using RenderHeads.Media.AVProVideo;
namespace NBF
{
public enum VideoPlayMode
{
Top,
Mid,
Bottom
}
public partial class VideoPlayer : GComponent
{
private VideoPlayerComponent _playerComponent;
private NTexture _texture;
private float _defY;
public bool IsLoading => stageCtrl.selectedIndex == 0;
private VideoRetData _videoRetData;
public int VideoIndex { get; private set; }
private void OnInited()
{
VideoManager.Instance.OnPlayStart += OnPlayStart;
VideoManager.Instance.OnHandleEvent += OnHandleEvent;
BtnPause.onClick.Set(OnClickPause);
}
SwipeGesture gesture = new SwipeGesture(BtnPause);
gesture.onBegin.Set(OnSwipeBegin);
gesture.onMove.Set(OnSwipeMove);
gesture.onEnd.Set(OnSwipeEnd);
gesture.onAction.Add(OnSwipeGesture);
_defY = VideoVer.y;
// Video.texture = new NTexture(Game.Instance.RT);
// Player.on
// Player.OpenMedia()
public void PlayVideo(int videoIndex, VideoPlayMode mode)
{
VideoIndex = videoIndex;
name = videoIndex.ToString();
gameObjectName = videoIndex.ToString();
if (VideoIndex < 0) return;
_videoRetData = Game.Instance.GetVideoDataByIndex(videoIndex);
if (_playerComponent != null)
{
StopVideo();
}
// stageCtrl.selectedIndex = 0;
// _videoRetData = videoRetData;
_playerComponent = VideoManager.Instance.GetPlayer(VideoIndex);
_playerComponent.VideoIndex = videoIndex;
_playerComponent.OnPlayStart += OnPlayStart;
_playerComponent.OnHandleEvent += OnHandleEvent;
var videoUrl = $"{Net.Instance.ServerUrl}/files/videos/{_videoRetData.FilePath}";
_playerComponent.ChangeVideo(videoUrl, mode == VideoPlayMode.Mid);
SetRt();
// _playerComponent =
}
public void StopVideo()
{
// var offset = _playerComponent.VideoIndex
// if(_playerComponent.VideoIndex)
_playerComponent.OnPlayStart -= OnPlayStart;
_playerComponent.OnHandleEvent -= OnHandleEvent;
}
protected override void OnUpdate()
{
base.OnUpdate();
UpdateTick();
}
public override void Dispose()
{
VideoManager.Instance.OnPlayStart -= OnPlayStart;
VideoManager.Instance.OnHandleEvent -= OnHandleEvent;
if (_texture != null)
{
_texture.Dispose();
}
StopVideo();
// if (_texture != null)
// {
// _texture.Dispose();
// }
base.Dispose();
}
#region
private float _offsetValue;
private void OnSwipeBegin(EventContext context)
{
}
private void OnSwipeMove(EventContext context)
{
var gesture = context.sender as SwipeGesture;
if (gesture == null) return;
Log.Info($"gesture.delta.y={gesture.delta.y}");
_offsetValue += gesture.delta.y;
VideoVer.y = _defY + _offsetValue;
}
private void OnSwipeEnd(EventContext context)
{
_offsetValue = 0;
VideoVer.y = _defY;
}
private void OnSwipeGesture(EventContext context)
{
SwipeGesture swipeGesture = (SwipeGesture)context.sender;
var value = Math.Abs(swipeGesture.position.y);
if (value < 200)
{
return;
}
if (swipeGesture.position.y < 0) //向上滑动
{
Log.Info($"向上滑动 y={swipeGesture.position.y}");
VideoManager.Instance.Next();
}
else
{
Log.Info($"向下滑动 y={swipeGesture.position.y}");
VideoManager.Instance.Previous();
}
VideoVer.alpha = 0;
}
#endregion
#region
private void OnHandleEvent(MediaPlayerEvent.EventType eventType)
{
if (isDisposed) return;
if (displayObject == null) return;
if (displayObject.gameObject == null) return;
if (eventType == MediaPlayerEvent.EventType.Paused)
{
// pauseCtrl.selectedIndex = 1;
pauseCtrl.selectedIndex = 1;
}
else if (eventType == MediaPlayerEvent.EventType.Unpaused)
{
pauseCtrl.selectedIndex = 0;
}
// else if (eventType == MediaPlayerEvent.EventType.Unpaused ||
// eventType == MediaPlayerEvent.EventType.Started)
// {
// // pauseCtrl.selectedIndex = 0;
// }
else if (eventType == MediaPlayerEvent.EventType.Started)
{
_watchCount = 1;
pauseCtrl.selectedIndex = 0;
stageCtrl.selectedIndex = 1;
StartedAnim.Play();
}
else if (eventType == MediaPlayerEvent.EventType.StartedSeeking)
{
_watchCount++;
Tick(); //重播时也上报tick
}
}
private void OnPlayStart(RenderTexture rt)
{
// if (_texture != null)
// {
// _texture.Dispose();
// }
//
// if (_playerComponent != null)
// {
// _texture = new NTexture(_playerComponent.NowRT);
// VideoVer.texture = _texture;
// }
if (_texture.width != rt.width || _texture.height != rt.height)
{
SetRt();
}
// _texture.width = rt.width;
// _texture.
stageCtrl.selectedIndex = 1;
}
private void SetRt()
{
if (_texture != null)
{
_texture.Dispose();
}
_texture = new NTexture(rt);
VideoVer.texture = _texture;
if (_playerComponent != null)
{
_texture = new NTexture(_playerComponent.NowRT)
{
destroyMethod = DestroyMethod.Custom
};
VideoVer.texture = _texture;
}
}
#endregion
#region
private void OnClickPause()
{
VideoManager.Instance.TogglePlayPause();
_playerComponent.TogglePlayPause();
}
#endregion
#region tick
private float _videoPlayTime;
private int _watchCount;
private void UpdateTick()
{
if (IsLoading) return;
if (_playerComponent.IsPlaying)
{
_videoPlayTime += Time.deltaTime;
if (_videoPlayTime >= 5)
{
Tick(); //5秒上报一次
}
}
}
private void Tick()
{
if (_videoRetData == null) return;
Net.Instance.Tick(_videoRetData.Id, (int)_videoPlayTime, _watchCount);
_watchCount = 0;
_videoPlayTime = 0;
}
#endregion

View File

@@ -0,0 +1,36 @@
using System;
namespace NBF
{
public static class GameUtil
{
/// <summary>
/// 格式化数字显示大于等于10000显示N万保留1位小数点整数1万、2万不要小数点
/// </summary>
/// <param name="number">要格式化的数字</param>
/// <returns>格式化后的字符串</returns>
public static string FormatNumber(this int number)
{
if (number < 10000)
{
return number.ToString(); // 小于10000直接显示
}
// 转换为万为单位
double valueInTenThousand = number / 10000.0;
// 判断是否为整数万
if (Math.Abs(valueInTenThousand - Math.Floor(valueInTenThousand)) < 0.00001) // 处理浮点数精度
{
// 整数万,不显示小数点
return $"{(int)valueInTenThousand}万";
}
// 非整数万向下取整并保留1位小数
double flooredValue = Math.Floor(valueInTenThousand * 10) / 10;
// 处理浮点数精度确保只显示1位小数
return $"{flooredValue:F1}万";
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f8eef66abe7f429ebc76870fe1d0e10c
timeCreated: 1770649984

View File

@@ -44,5 +44,64 @@ namespace NBF
Debug.LogWarning($"androidId={androidId}");
return androidId;
}
public static string GetDeviceModel()
{
string deviceModel = string.Empty;
#if UNITY_EDITOR
// 在编辑器中使用 SystemInfo
deviceModel = SystemInfo.deviceModel;
#elif UNITY_ANDROID
if (Application.platform == RuntimePlatform.Android)
{
try
{
// 方法1使用 SystemInfo.deviceModel推荐最简单
deviceModel = SystemInfo.deviceModel;
// 方法2通过 Android API 获取更详细的信息(可选)
/*
using (AndroidJavaClass buildClass = new AndroidJavaClass("android.os.Build"))
{
string manufacturer = buildClass.GetStatic<string>("MANUFACTURER");
string model = buildClass.GetStatic<string>("MODEL");
string product = buildClass.GetStatic<string>("PRODUCT");
string device = buildClass.GetStatic<string>("DEVICE");
// 可以根据需要组合不同的信息
deviceModel = $"{manufacturer} {model}";
// 或者更详细的deviceModel = $"{manufacturer} {model} (Product: {product}, Device: {device})";
}
*/
}
catch (System.Exception e)
{
Debug.LogError("Error while fetching device model: " + e.Message);
deviceModel = SystemInfo.deviceModel; // 失败时回退到 SystemInfo
}
}
else
{
deviceModel = SystemInfo.deviceModel;
}
#elif UNITY_IOS
// iOS平台
deviceModel = SystemInfo.deviceModel;
// 如果需要获取更友好的设备名称(如 "iPhone 14 Pro" 而不是 "iPhone15,2"
if (Application.platform == RuntimePlatform.IPhonePlayer)
{
deviceModel = UnityEngine.iOS.Device.generation.ToString();
}
#else
// 其他平台
deviceModel = SystemInfo.deviceModel;
#endif
Debug.LogWarning($"Device Model: {deviceModel}");
return deviceModel;
}
}
}