我想实现在线视频播放功能并下载它.我的意思是应该使用相同的下载流进行下载和播放,以便保存视频以供离线使用,并防止分别播放和下载两倍的数据费用.
到目前为止,我已经实现了视频下载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{ @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的localhost url.
您将需要处理缓冲,同步线程等.
在Milos Fec
答案的帮助下,我解决了这个问题.我必须创建两个用于下载的线程1和用于通过socketServer下载内容的流式传输,同时负责下载的数据和正在播放的数据的同步.
我把整个代码作为一个库放在github上检查这里