public bool setSeekTime(float seekTime) { if (decoderState != DecoderNative.DecoderState.SEEK_FRAME && decoderState >= DecoderNative.DecoderState.START) { lastState = decoderState; decoderState = DecoderNative.DecoderState.SEEK_FRAME; var setTime = 0.0f; if (isVideoEnabled && seekTime > videoTotalTime || isAudioEnabled && !isAllAudioChEnabled && seekTime > audioTotalTime || isVideoReadyToReplay || isAudioReadyToReplay || seekTime < 0.0f) { print(LOG_TAG + " Seek over end. "); setTime = 0.0f; } else { setTime = seekTime; } print(LOG_TAG + " set seek time: " + setTime); hangTime = setTime; DecoderNative.nativeSetSeekTime(decoderID, setTime); DecoderNative.nativeSetVideoTime(decoderID, setTime); if (isAudioEnabled && !isAllAudioChEnabled) { lock (_lock) { audioDataBuff.Clear(); } audioProgressTime = firstAudioFrameTime = -1.0; foreach (var src in audioSource) { src.Stop(); } } return(true); } return(false); }
// Video progress is triggered using Update. Progress time would be set by nativeSetVideoTime. private void Update() { switch (decoderState) { case DecoderNative.DecoderState.START: if (isVideoEnabled) { // Prevent empty texture generate green screen.(default 0,0,0 in YUV which is green in RGB) if (useDefault && DecoderNative.nativeIsContentReady(decoderID)) { getTextureFromNative(); setTextures(videoTexYch, videoTexUch, videoTexVch); useDefault = false; } // Update video frame by dspTime. var setTime = curRealTime - globalStartTime; // Normal update frame. if (setTime < videoTotalTime || videoTotalTime <= 0) { if (seekPreview && DecoderNative.nativeIsContentReady(decoderID)) { setPause(); seekPreview = false; unmute(); } else { DecoderNative.nativeSetVideoTime(decoderID, (float)setTime); GL.IssuePluginEvent(DecoderNative.GetRenderEventFunc(), decoderID); } } else { isVideoReadyToReplay = true; } } if (DecoderNative.nativeIsVideoBufferEmpty(decoderID) && !DecoderNative.nativeIsEOF(decoderID)) { decoderState = DecoderNative.DecoderState.BUFFERING; hangTime = curRealTime - globalStartTime; } break; case DecoderNative.DecoderState.SEEK_FRAME: if (DecoderNative.nativeIsSeekOver(decoderID)) { globalStartTime = curRealTime - hangTime; decoderState = DecoderNative.DecoderState.START; if (lastState == DecoderNative.DecoderState.PAUSE) { seekPreview = true; mute(); } } break; case DecoderNative.DecoderState.BUFFERING: if (!DecoderNative.nativeIsVideoBufferEmpty(decoderID) || DecoderNative.nativeIsEOF(decoderID)) { decoderState = DecoderNative.DecoderState.START; globalStartTime = curRealTime - hangTime; } break; case DecoderNative.DecoderState.PAUSE: case DecoderNative.DecoderState.EOF: default: break; } if (isVideoEnabled || isAudioEnabled) { if ((!isVideoEnabled || isVideoReadyToReplay) && (!isAudioEnabled || isAudioReadyToReplay)) { decoderState = DecoderNative.DecoderState.EOF; isVideoReadyToReplay = isAudioReadyToReplay = false; if (onVideoEnd != null) { onVideoEnd.Invoke(); } } } }