下载视频和播放

时间:2015-12-19 13:18:19

标签: 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中的评论中有一些代码,我试图实现我的目标,但它说&#34;无法播放视频&#34;。 谁知道解决方案?请帮帮我。

2 个答案:

答案 0 :(得分:8)

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

创建两个后台主题:下载主题流式主题

流媒体广告中创建 ServerSocket 并流式传输刚刚下载的数据。

在VideoView中打开ServerSocket的localhost url。

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

答案 1 :(得分:5)

Milos Fec的回答的帮助下,我解决了这个问题。 我必须创建两个用于下载的线程1和用于通过socketServer下载内容的流式传输,同时负责下载的数据和正在播放的数据的同步。

我已将整个代码作为库放在github check here