我正在Unity中实现一个VR 360视频查看器,并需要实现“倒放”功能。一些尝试但显然失败的方法如下:
- 结果:视频暂停
- 将VideoPlayer的playbackSpeed字段设置为负数。
- 结果:视频暂停
- 按照这里建议的方法逐帧反转视频。
- 结果:播放非常卡顿
- 使用Vive Media Player(基于ffmpeg构建)而不是默认的VideoPlayer(链接:https://assetstore.unity.com/packages/tools/video/vive-media-decoder-63938),逐帧反转视频并在每次Update()调用时强制渲染器渲染该帧,即使解码器的状态为解码器状态.SEEK_FRAME。
// Video progress is triggered using Update. Progress time would be set by nativeSetVideoTime.
void Update() {
Debug.Log(decoderState);
switch (decoderState) {
case DecoderState.START:
if (isVideoEnabled) {
// Prevent empty texture generate green screen.(default 0,0,0 in YUV which is green in RGB)
if (useDefault && nativeIsContentReady(decoderID)) {
getTextureFromNative();
setTextures(videoTexYch, videoTexUch, videoTexVch);
useDefault = false;
}
// Update video frame by dspTime.
double setTime = AudioSettings.dspTime - globalStartTime;
// Normal update frame.
if (setTime < videoTotalTime || videoTotalTime == -1.0f) {
if (seekPreview && nativeIsContentReady(decoderID)) {
setPause();
seekPreview = false;
unmute();
} else {
nativeSetVideoTime(decoderID, (float) setTime);
GL.IssuePluginEvent(GetRenderEventFunc(), decoderID);
}
} else {
isVideoReadyToReplay = true;
}
}
if (nativeIsVideoBufferEmpty(decoderID) && !nativeIsEOF(decoderID)) {
decoderState = DecoderState.BUFFERING;
hangTime = AudioSettings.dspTime - globalStartTime;
}
break;
case DecoderState.SEEK_FRAME:
//
// Code Added:
//
setTime = AudioSettings.dspTime - globalStartTime;
nativeSetVideoTime(decoderID, (float) setTime);
GL.IssuePluginEvent(GetRenderEventFunc(), decoderID);
//
//
if (nativeIsSeekOver(decoderID)) {
globalStartTime = AudioSettings.dspTime - hangTime;
decoderState = DecoderState.START;
if (lastState == DecoderState.PAUSE) {
seekPreview = true;
mute();
}
}
break;
case DecoderState.BUFFERING:
if (nativeIsVideoBufferFull(decoderID) || nativeIsEOF(decoderID)) {
decoderState = DecoderState.START;
globalStartTime = AudioSettings.dspTime - hangTime;
}
break;
case DecoderState.PAUSE:
case DecoderState.EOF:
default:
break;
}
if (isVideoEnabled || isAudioEnabled) {
if ((!isVideoEnabled || isVideoReadyToReplay) && (!isAudioEnabled || isAllAudioChEnabled || isAudioReadyToReplay)) {
decoderState = DecoderState.EOF;
isVideoReadyToReplay = isAudioReadyToReplay = false;
if (onVideoEnd != null) {
onVideoEnd.Invoke();
}
}
}
}
- 结果:视频暂停
我目前通过预先生成反向视频,每当用户想要倒带时切换到反向视频来解决这个问题。然而,考虑到我们的项目使用多个360视频并允许自定义视频,生成反向视频所需要的时间和切换视频所需的延迟时间是不可接受的。
由于该功能直观易懂,我认为一定存在更简单的解决方案。我已经陷入这个问题很久了,因此任何有关解决问题的指示都将是一个巨大的帮助!