在 VideoView 上流式传输视频

Posted

技术标签:

【中文标题】在 VideoView 上流式传输视频【英文标题】:Streaming videos on VideoView 【发布时间】:2016-03-17 08:55:15 【问题描述】:

我有一个简单的VideoView,我正在尝试从 URL 流式传输视频。这是我的代码:

//everything is in onCreate()

videoView = (VideoView)findViewById(R.id.video);

String videoAddress = "https://archive.org/download/ksnn_compilation_master_the_internet/ksnn_compilation_master_the_internet_512kb.mp4";
Uri videoUri = Uri.parse(videoAddress);

videoView.setVideoURI(videoUri);
videoView.start();
videoController = new MediaController(this);
videoController.setAnchorView(videoView);
videoView.setMediaController(videoController);

问题:

开始播放视频大约需要 7-8 秒。一直缓冲到那时。

这与互联网连接无关,因为我在浏览器中在同一个互联网上同时播放了相同的视频。 (与应用程序并行运行浏览器)。在浏览器中启动视频只需要 1-2 秒。

我也尝试了其他几个来自不同来源的视频,但我都面临着这种滞后。

在 SO 上已多次提出类似问题,但均未得到解答。

【问题讨论】:

【参考方案1】:

问题是,我在 UI 线程中做所有事情,这使得它需要很长时间。在AsyncTask 中做所有事情,一切都会好起来的。

对于初学者,this link 描述了您如何在AsyncTask 中做到这一点。

定义一个扩展AsyncTask的类:

public class BackgroundAsyncTask extends AsyncTask<String, Uri, Void> 
    Integer track = 0;
    ProgressDialog dialog;

    protected void onPreExecute() 
        dialog = new ProgressDialog(PlayVideo.this);
        dialog.setMessage("Loading, Please Wait...");
        dialog.setCancelable(true);
        dialog.show();
    

    protected void onProgressUpdate(final Uri... uri) 

        try 

            media=new MediaController(PlayVideo.this);
            video.setMediaController(media);
            media.setPrevNextListeners(new View.OnClickListener() 
                @Override
                public void onClick(View v) 
                    // next button clicked

                
            , new View.OnClickListener() 
                @Override
                public void onClick(View v) 

                    finish();
                
            );
            media.show(10000);

            video.setVideoURI(uri[0]);
            video.requestFocus();
            video.setOnPreparedListener(new OnPreparedListener() 

                public void onPrepared(MediaPlayer arg0) 
                    video.start();
                    dialog.dismiss();
                
            );


         catch (IllegalArgumentException e) 
            e.printStackTrace();
         catch (IllegalStateException e) 
            e.printStackTrace();
         catch (SecurityException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        


    

    @Override
    protected Void doInBackground(String... params) 
        try 
            Uri uri = Uri.parse(params[0]);

            publishProgress(uri);
         catch (Exception e) 
            e.printStackTrace();

        

        return null;
    


那么,在onCreate()方法中,调用这个BackgroundAsynchTaskexecute()方法即可:

video = (VideoView) findViewById(R.id.video);
new BackgroundAsyncTask().execute("link-to-the-video");

【讨论】:

以上是关于在 VideoView 上流式传输视频的主要内容,如果未能解决你的问题,请参考以下文章

如何在 videoview 中流式传输视频时删除空白?

Android VideoView 流式传输

如何同时播放/流式传输视频并将其保存到应用缓存?

如何更改 android videoview 中流式传输的缓冲区大小?

如何使用来自外部设备的 setVideoURI 流从 android videoview 获取帧?

VideoView 大小不适合屏幕