使用VideoView实现无缝视频循环

104
我有以下代码,可以将视频作为原始资源获取,启动视频并循环播放,但我需要视频无缝循环播放。 当现在视频结束并重新开始时,过渡会导致闪烁一小段时间,这对于我的应用程序来说是无法容忍的。

我有以下代码,可以将视频作为原始资源获取,启动视频并循环播放,但我需要视频无缝循环播放。 当现在视频结束并重新开始时,过渡会导致闪烁一小段时间,这对于我的应用程序来说是无法容忍的。

public class Example extends Activity {
    VideoView vv;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        vv = (VideoView)findViewById(R.id.VideoView01);

        //Video Loop
        vv.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            public void onCompletion(MediaPlayer mp) {
                vv.start(); //need to make transition seamless.
            }
        });

        Uri uri = Uri.parse("android.resource://com.example/"
                + R.raw.video);

        vv.setVideoURI(uri);
        vv.requestFocus();    
        vv.start();
    }
}

这段剪辑只有22秒长,但是它被设计成无缝的,所以可以在没有延迟的情况下进行工作。

8个回答

257

尝试以下代码,它可以百分百地工作:


VideoView videoView;<---在方法之外编写此代码或将其声明为最终变量。

videoView.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        mp.setLooping(true);
    }
});

每个循环仍然会重新缓冲,对我来说不如之前的方法流畅。 - Pencilcheck
@Pencilcheck 这是一个简单的本地视频循环,如果你想用它来处理URL和缓冲,那么你需要实现其他逻辑。 - PravinDodia
提醒大家,这对本地视频也不起作用。如果您播放一个有恒定声音的视频,您会听到循环之间的暂停。 - Edison
1
@PravinDodia 它可以用于mp4视频(文件),但无法与m3u8一起使用。如果您对m3u8文件有任何想法,请给我建议。 - Maroti
2
@PravinDodia 感谢您提供的信息。是的,我已经使用了流视频。我在MediaPlayer.OnCompletionListener()中使用了vv.start()而不是循环。 - Maroti
显示剩余2条评论

19

在 Kotlin 中简单使用

videoView.setOnPreparedListener { it.isLooping = true }

9

不确定多年后这是否有所帮助,但我使用了

vv.start();
vv.setOnCompletionListener ( new MediaPlayer.OnCompletionListener() {

 @Override 
  public void onCompletion(MediaPlayer mediaPlayer) {   
    vv.start();
  }
});

并且它具有无缝循环。

5
暂停是为了让底层的MediaPlayer刷新缓冲区。需要多长时间取决于许多因素,其中许多因素是您无法控制的(例如CPU速度、内置闪存存储器速度)。
你可以控制的一个因素是将视频从资源中提取到文件系统中。资源存储在APK中,这是一个ZIP文件,因此以这种方式提取视频可能需要额外的时间。
您可能需要切换到SurfaceView并使用两个MediaPlayers,在它们之间交替--一个正在播放,而另一个正在准备,因此当播放结束时,您可以切换到新的播放器。我没有尝试过这种方法,因此我不知道可能会有什么后果。但是,我知道这种技术经常用于音频播放,以从一个剪辑转换到另一个剪辑。

如果我没记错的话,当MediaPlayer在准备时会占用SurfaceView,因此在一个MediaPlayer正在使用它时,您无法准备另一个MediaPlayer。 - Edison

2

有点晚了,但是你不能使用以下方法吗?

MediaPlayer.setLooping(true);

1
这是很久以前的事了,但我认为当调用循环时,视频中有明显的暂停。 - SamRowley

1
如果您正在使用Kotlin
 videoView.setOnPreparedListener(object : MediaPlayer.OnPreparedListener {
                override fun onPrepared(mp: MediaPlayer?) {
                    //Start Playback
                    videoView.start()
                    //Loop Video
                    mp!!.isLooping = true;
                    Log.i(TAG, "Video Started");
                }
            });

使用箭头表达式的简写形式
videoView.setOnPreparedListener { mp ->
            //Start Playback
            videoView.start()
            //Loop Video
            mp!!.isLooping = true;
            Log.i(TAG, "Video Started");
        };

0

0

解决方法是从视频中删除音频并将其转换为无缝循环的.ogg文件,然后使用没有音频的视频进行循环播放即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接