android - 一边播放一边下载视频

标签 android

我想在下载的同时实现在线视频播放功能。我的意思是应该使用相同的下载流来下载和播放,以便可以保存视频以供离线使用,并防止单独播放和下载的两倍数据费用。

到目前为止,我已经使用 asyncTask 实现了视频下载并在 OnPostExecute 上播放。以下是代码:

public class MainActivity extends AppCompatActivity {


private Button btnPlay;
private MediaPlayer player;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    outFilePath = getExternalFilesDir("/") + "/video.mp4";
    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });

    prepareVideoView();

}

private VideoView videoView;
String videoPath = "http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_5mb.mp4";
String outFilePath = "";//

private void prepareVideoView() {
    MediaController mediaController = new MediaController(this);
    videoView = (VideoView) findViewById(R.id.videoView);
    mediaController.setAnchorView(videoView);
    videoView.setMediaController(mediaController);
    btnPlay = (Button) findViewById(R.id.btnPlayVideo);
    btnPlay.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            new VideoDownloader().execute(videoPath);
        }
    });

    videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            player = mp;

            player.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
                @Override
                public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
                    Log.w("download","size changed");
                }
            });
        }
    });
}
File outFile;
class VideoDownloader extends AsyncTask<String, Integer, Void> {

    @Override
    protected Void doInBackground(String... params) {


        outFile = new File(outFilePath);
        FileOutputStream out = null;
        BufferedInputStream input = null;
        try {
            out = new FileOutputStream(outFile,true);

            try {
                URL url = new URL(videoPath);

                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.connect();
                if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                    throw new RuntimeException("response is not http_ok");
                }
                int fileLength = connection.getContentLength();

                input = new BufferedInputStream(connection.getInputStream());
                byte data[] = new byte[2048];
                long readBytes = 0;
                int len;
                boolean flag = true;
                int readb = 0;
                while ((len = input.read(data)) != -1) {
                    out.write(data,0,len);
                    readBytes += len;
   // Following commented code is to play video along with downloading but not working.
/*                      readb += len;
                    if(readb > 1000000)
                    {
                        out.flush();
                        playVideo();
                        readb = 0;
                    }
*/
                    Log.w("download",(readBytes/1024)+"kb of "+(fileLength/1024)+"kb");
                }



            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (out != null)
                    out.flush();
                    out.close();
                if(input != null)
                    input.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        Log.w("download", "Done");
       playVideo();

    }
}

private void playVideo() {

    videoView.setVideoPath(outFile.getAbsolutePath());
    videoView.start();
}
}

以上代码可以正常下载然后播放。 DoInBackground 中的注释中有一些代码行,我试图实现我的目标,但它说“无法播放视频”。 有人知道解决方案吗?请帮助我。

最佳答案

您可以创建本地代理来保存流。

创建两个后台线程:下载线程流线程

流线程中创建ServerSocket并流式传输刚刚下载的数据。

在 VideoView 中打开您的 ServerSocket 的本地主机 url。

您将需要处理缓冲、同步线程等。

关于android - 一边播放一边下载视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34371224/

相关文章:

android - 更改调用屏幕

java.lang.NoClassDefFoundError : Failed resolution of: Lcom/google/android/maps/GeoPoint

android - Android webView 中的阿拉伯语自定义字体

android - 异步任务的实现

java - 如何从偏航、俯仰和滚动中获取 RotationMatrix

android - 在布局内的运行时多次膨胀一个布局

java - 从另一个 Activity 的共享首选项获取字符串集

android - 使用低于 compileSdkVersion 的支持库版本

android - 是否可以通过 Xamarin Forms 项目访问在 ANDROID 项目中编码的自定义控件?

java - 尝试将邮件发送到动态电子邮件 ID 时出现错误