`/**
* 本实例演示如何在Android中播放网络上的视频,这里牵涉到视频传输协议,视频编解码等知识点
* @author Administrator
*Android当前支持两种协议来传输视频流一种是Http协议,另一种是RTSP协议
*Http协议最常用于视频下载等,但是目前还不支持边传输边播放的实时流媒体
*同时,在使用Http协议 传输视频时,需要根据不同的网络方式来选择合适的编码方式,
*比如对于GPRS网络,其带宽只有20kbps,我们需要使视频流的传输速度在此范围内。
*比如,对于GPRS来说,如果多媒体的编码速度是400kbps,那么对于一秒钟的视频来说,就需要20秒的时间。这显然是无法忍受的
*Http下载时,在设备上进行缓存,只有当缓存到一定程度时,才能开始播放。
*
*所以,在不需要实时播放的场合,我们可以使用Http协议
*
*RTSP:Real Time Streaming Protocal,实时流媒体传输控制协议。
*使用RTSP时,流媒体的格式需要是RTP。
*RTSP和RTP是结合使用的,RTP单独在Android中式无法使用的。
*
*RTSP和RTP就是为实时流媒体设计的,支持边传输边播放。
*
*同样的对于不同的网络类型(GPRS,3G等),RTSP的编码速度也相差很大。根据实际情况来
*
*使用前面介绍的三种方式,都可以播放网络上的视频,唯一不同的就是URI
*
*本例中使用VideoView来播放网络上的视频
*/ `
videoview = (VideoView) findViewById(R.id.videoview);
Uri uri = Uri.parse("http://7sbsl4.com1.z0.glb.clouddn.com/gogogo.mp4");
videoview.setVideoURI(uri);
videoview.requestFocus();
videoview.start();
没有管理MediaPalyer的各种状态,这些状态都让VideoView给封装了,并且,当VideoView创建的时候,MediaPalyer对象将会创建,当VideoView对象销毁的时候,MediaPlayer对象将会释放。
/**
* 视频或者音频到结尾时触发的方法
*/
videoview.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
Log.i("通知", "完成");
}
});
/**
* 注册一个错误监听,这个全部写出来了,只是为了当遇到错误时做个参考吧,第一次用SurfaceView做的时候遇到了问题
*/
videoview.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.i("通知", "播放中出现错误");
switch (what) {
case -1004:
Log.d("Streaming Media", "MEDIA_ERROR_IO");
break;
case -1007:
Log.d("Streaming Media", "MEDIA_ERROR_MALFORMED");
break;
case 200:
Log.d("Streaming Media", "MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK");
break;
case 100:
Log.d("Streaming Media", "MEDIA_ERROR_SERVER_DIED");
break;
case -110:
Log.d("Streaming Media", "MEDIA_ERROR_TIMED_OUT");
break;
case 1:
Log.d("Streaming Media", "MEDIA_ERROR_UNKNOWN");
break;
case -1010:
Log.d("Streaming Media", "MEDIA_ERROR_UNSUPPORTED");
break;
}
switch (extra) {
case 800:
Log.d("Streaming Media", "MEDIA_INFO_BAD_INTERLEAVING");
break;
case 702:
Log.d("Streaming Media", "MEDIA_INFO_BUFFERING_END");
break;
case 701:
Log.d("Streaming Media", "MEDIA_INFO_METADATA_UPDATE");
break;
case 802:
Log.d("Streaming Media", "MEDIA_INFO_METADATA_UPDATE");
break;
case 801:
Log.d("Streaming Media", "MEDIA_INFO_NOT_SEEKABLE");
break;
case 1:
Log.d("Streaming Media", "MEDIA_INFO_UNKNOWN");
break;
case 3:
Log.d("Streaming Media", "MEDIA_INFO_VIDEO_RENDERING_START");
break;
case 700:
Log.d("Streaming Media", "MEDIA_INFO_VIDEO_TRACK_LAGGING");
break;
}
return false;
}
});
下面是新增的。因为videoview刚进入界面太挫了一片漆黑。。个人技术太菜就找了一个获取网络视频缩略图的方法给他设置个背景:
鉴于多数人都用过ThumbnailUtils.createVideoThumbnail()方法,该方法在2.x系统下可用,API LEVEL > 14时却只能返回null,以下为解决该问题方案:
之后再自己的后台线程中调用该方法得到网络视频的缩略图bitmap然后在主线程中调用imageView.setImageBitmap(bitmap)即可;
获取缩略图代码:
private Bitmap createVideoThumbnail(String url, int width, int height) {
Bitmap bitmap = null;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
int kind = MediaStore.Video.Thumbnails.MINI_KIND;
try {
if (Build.VERSION.SDK_INT >= 14) {
retriever.setDataSource(url, new HashMap());
} else {
retriever.setDataSource(url);
}
bitmap = retriever.getFrameAtTime();
} catch (IllegalArgumentException ex) {
// Assume this is a corrupt video file
} catch (RuntimeException ex) {
// Assume this is a corrupt video file.
} finally {
try {
retriever.release();
} catch (RuntimeException ex) {
// Ignore failures while cleaning up.
}
}
if (kind == Images.Thumbnails.MICRO_KIND && bitmap != null) {
bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
}
return bitmap;
}