Tôi muốn triển khai chức năng phát video trực tuyến cùng với việc tải xuống. Tôi có nghĩa là cùng một luồng tải xuống nên được sử dụng để tải xuống và phát để video có thể được lưu để sử dụng ngoại tuyến và ngăn chặn hai lần chi phí dữ liệu để phát và tải xuống riêng biệt.Tải xuống video cùng với chơi
Cho đến nay tôi đã triển khai tải xuống video với asyncTask
và phát video trên OnPostExecute
. Sau đây là mã:
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();
}
}
Mã trên đang hoạt động bình thường để tải xuống và sau đó phát. Có một số dòng mã trong bình luận trong DoInBackground
mà tôi đã cố gắng để đạt được mục tiêu của tôi nhưng nó nói "không thể chơi video". Bất cứ ai biết về giải pháp? làm ơn giúp tôi.
Bạn có yêu cầu về trình chiếu một video giống như những gì xảy ra trong Youtube? – midhunhk
trong youtube chỉ có luồng tôi nghĩ. những gì tôi cần là chỉ sử dụng một inputstream để chơi video trực tuyến và lưu nó cho mục đích ngoại tuyến. – chandil03
Phương thức 'playVideo()' của bạn sử dụng một tệp có 'setVideoPath()'. Nói cách khác, 'playVideo()' sẽ * chỉ * hoạt động với video được tải xuống đầy đủ trên đĩa. Bạn sẽ cần phải truyền các khung và âm thanh riêng lẻ đến một trình phát đa phương tiện để truyền trực tuyến, sau đó chỉ cần chuyển các byte đó vào một tệp sau khi xem bộ nhớ cache để sử dụng ngoại tuyến. – MeetTitan