如何根据 android 中的缓冲区 %age 在来自 url 的视频视图中播放视频?
How to play video in video view from url based on buffer %age in android?
我有一个来自 s3 服务器的 link 视频,我正在 VideoView 上播放这个视频。视频播放正常,但问题是它首先下载整个视频然后播放。
我希望它像缓冲区一样播放。我的意思是,如果下载了 20% 的视频,它应该播放这些视频,然后再次下载(就像在 youtube 中一样)。这是我的代码,我所做的是..
FFmpegMediaMetadataRetriever mediaMetadataRetriever = new FFmpegMediaMetadataRetriever();
AWSCredentials myCredentials = new BasicAWSCredentials(
"AKIAIGOIY4LLB7EMACGQ",
"7wNQeY1JC0uyMaGYhKBKc9V7QC7X4ecBtyLimt2l");
AmazonS3 s3client = new AmazonS3Client(myCredentials);
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(
"mgvtest", videoUrl);
URL objectURL = s3client.generatePresignedUrl(request);
try {
mediaMetadataRetriever.setDataSource(videoUrl);
} catch (Exception e) {
utilDialog.showDialog("Unable to load this video",
utilDialog.ALERT_DIALOG);
pb.setVisibility(View.INVISIBLE);
}
videoView.setVideoURI(Uri.parse(videoUrl));
MediaController myMediaController = new MediaController(this);
// myMediaController.setMediaPlayer(videoView);
videoView.setMediaController(myMediaController);
videoView.setOnCompletionListener(myVideoViewCompletionListener);
videoView.setOnPreparedListener(MyVideoViewPreparedListener);
videoView.setOnErrorListener(myVideoViewErrorListener);
videoView.requestFocus();
videoView.start();
听众
MediaPlayer.OnCompletionListener myVideoViewCompletionListener = new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer arg0) {
// Toast.makeText(PlayRecordedVideoActivity.this, "End of Video",
// Toast.LENGTH_LONG).show();
}
};
MediaPlayer.OnPreparedListener MyVideoViewPreparedListener = new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
pb.setVisibility(View.INVISIBLE);
imgScreenshot.setVisibility(View.VISIBLE);
tvScreenshot.setVisibility(View.VISIBLE);
// final Animation in = new AlphaAnimation(0.0f, 1.0f);
// in.setDuration(3000);
// tvScreenshot.startAnimation(in);
Animation animation = AnimationUtils.loadAnimation(
getApplicationContext(), R.anim.zoom_in);
tvScreenshot.startAnimation(animation);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
tvScreenshot.setVisibility(View.INVISIBLE);
}
}, 3000);
}
};
MediaPlayer.OnErrorListener myVideoViewErrorListener = new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
// Toast.makeText(PlayRecordedVideoActivity.this, "Error!!!",
// Toast.LENGTH_LONG).show();
return true;
}
};
实际上你必须使用 s3 启动 cloudfront,这样才能流式传输 s3 视频,
查看此 link 了解更多信息:
http://www.miracletutorials.com/s3-streaming-video-with-cloudfront/
为了能够在完全下载之前开始播放 mp4 视频,视频必须在视频的开头而不是结尾处包含元数据 - 不幸的是,标准 mp4 默认情况下通常位于结束。
元数据在 'atom' 或 'box' 中(基本上是 mp4 文件中的数据结构),可以移至开头。这通常称为 faststart,ffmpeg 等工具将允许您执行此操作。以下是ffmpeg文档的摘录:
The mov/mp4/ismv muxer supports fragmentation. Normally, a MOV/MP4 file has all the metadata about all packets stored in one location (written at the end of the file, it can be moved to the start for better playback by adding faststart to the movflags, or using the qt-faststart tool).
还有其他工具和软件也可以让您执行此操作 - 例如上面 ffmpeg 摘录中提到的那个:
如果您真的想要完全流式传输,其中服务器将文件分成块并由客户端一个一个地下载,那么您可能想要使用一种自适应比特率协议(Apple 的 HLS、MS 的 Smoothstreaming、 Adobe Adaptive Streaming 或新的开放标准 DASH)。这也允许您有不同的比特率以适应不同的网络条件。您将需要一个可以支持此功能的服务器来使用这些技术。如果您只想要一个只有一个视频的简单网站并且不会有太多流量,这可能有点过分了。
我有一个来自 s3 服务器的 link 视频,我正在 VideoView 上播放这个视频。视频播放正常,但问题是它首先下载整个视频然后播放。
我希望它像缓冲区一样播放。我的意思是,如果下载了 20% 的视频,它应该播放这些视频,然后再次下载(就像在 youtube 中一样)。这是我的代码,我所做的是..
FFmpegMediaMetadataRetriever mediaMetadataRetriever = new FFmpegMediaMetadataRetriever();
AWSCredentials myCredentials = new BasicAWSCredentials(
"AKIAIGOIY4LLB7EMACGQ",
"7wNQeY1JC0uyMaGYhKBKc9V7QC7X4ecBtyLimt2l");
AmazonS3 s3client = new AmazonS3Client(myCredentials);
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(
"mgvtest", videoUrl);
URL objectURL = s3client.generatePresignedUrl(request);
try {
mediaMetadataRetriever.setDataSource(videoUrl);
} catch (Exception e) {
utilDialog.showDialog("Unable to load this video",
utilDialog.ALERT_DIALOG);
pb.setVisibility(View.INVISIBLE);
}
videoView.setVideoURI(Uri.parse(videoUrl));
MediaController myMediaController = new MediaController(this);
// myMediaController.setMediaPlayer(videoView);
videoView.setMediaController(myMediaController);
videoView.setOnCompletionListener(myVideoViewCompletionListener);
videoView.setOnPreparedListener(MyVideoViewPreparedListener);
videoView.setOnErrorListener(myVideoViewErrorListener);
videoView.requestFocus();
videoView.start();
听众
MediaPlayer.OnCompletionListener myVideoViewCompletionListener = new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer arg0) {
// Toast.makeText(PlayRecordedVideoActivity.this, "End of Video",
// Toast.LENGTH_LONG).show();
}
};
MediaPlayer.OnPreparedListener MyVideoViewPreparedListener = new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
pb.setVisibility(View.INVISIBLE);
imgScreenshot.setVisibility(View.VISIBLE);
tvScreenshot.setVisibility(View.VISIBLE);
// final Animation in = new AlphaAnimation(0.0f, 1.0f);
// in.setDuration(3000);
// tvScreenshot.startAnimation(in);
Animation animation = AnimationUtils.loadAnimation(
getApplicationContext(), R.anim.zoom_in);
tvScreenshot.startAnimation(animation);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
tvScreenshot.setVisibility(View.INVISIBLE);
}
}, 3000);
}
};
MediaPlayer.OnErrorListener myVideoViewErrorListener = new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
// Toast.makeText(PlayRecordedVideoActivity.this, "Error!!!",
// Toast.LENGTH_LONG).show();
return true;
}
};
实际上你必须使用 s3 启动 cloudfront,这样才能流式传输 s3 视频, 查看此 link 了解更多信息: http://www.miracletutorials.com/s3-streaming-video-with-cloudfront/
为了能够在完全下载之前开始播放 mp4 视频,视频必须在视频的开头而不是结尾处包含元数据 - 不幸的是,标准 mp4 默认情况下通常位于结束。
元数据在 'atom' 或 'box' 中(基本上是 mp4 文件中的数据结构),可以移至开头。这通常称为 faststart,ffmpeg 等工具将允许您执行此操作。以下是ffmpeg文档的摘录:
The mov/mp4/ismv muxer supports fragmentation. Normally, a MOV/MP4 file has all the metadata about all packets stored in one location (written at the end of the file, it can be moved to the start for better playback by adding faststart to the movflags, or using the qt-faststart tool).
还有其他工具和软件也可以让您执行此操作 - 例如上面 ffmpeg 摘录中提到的那个:
如果您真的想要完全流式传输,其中服务器将文件分成块并由客户端一个一个地下载,那么您可能想要使用一种自适应比特率协议(Apple 的 HLS、MS 的 Smoothstreaming、 Adobe Adaptive Streaming 或新的开放标准 DASH)。这也允许您有不同的比特率以适应不同的网络条件。您将需要一个可以支持此功能的服务器来使用这些技术。如果您只想要一个只有一个视频的简单网站并且不会有太多流量,这可能有点过分了。