Android提高之MediaPlayer播放网络视频的实现方法

前面讲解了MediaPlayer播放网络音频,主要介绍了MediaPlayer关于网络音频的缓冲和进度条控制的方法,本文再来讲解一下MediaPlayer播放网络视频的方法。播放网络视频比播放网络音频需要多一个SurfaceView而已,在已经熟悉了MediaPlayer播放网络音频之后,相信大家对本文所述的播放网络视频也能很快地掌握。

先来看看本文程序运行截图,如下所示:

本文程序的视频来自http://daily3gp.com,大家可以替换程序中的视频链接,试试其他影片。

main.xml的源码如下:

<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:layout_width="fill_parent"> <SurfaceView android:id="@+id/surfaceView1" android:layout_height="fill_parent" android:layout_width="fill_parent"></SurfaceView> <LinearLayout android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_gravity="bottom" android:orientation="vertical"> <LinearLayout android:orientation="horizontal" android:layout_gravity="center_horizontal" android:layout_marginTop="4.0dip" android:layout_height="wrap_content" android:layout_width="wrap_content"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnPlayUrl" android:text="播放网络视频"></Button> <Button android:layout_height="wrap_content" android:id="@+id/btnPause" android:text="暂停" android:layout_width="80dip"></Button> <Button android:layout_height="wrap_content" android:layout_width="80dip" android:text="停止" android:id="@+id/btnStop"></Button> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="20dip"> <SeekBar android:paddingRight="10dip" android:layout_gravity="center_vertical" android:paddingLeft="10dip" android:layout_weight="1.0" android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/skbProgress" android:max="100"></SeekBar> </LinearLayout> </LinearLayout> </FrameLayout>

Player.java是本文的核心,Player.java实现了“进度条更新”、“数据缓冲”、“SurfaceHolder生命周期”等功能,其中“SurfaceHolder生命周期”是视频与音频播放的最大区别,通过surfaceCreated()、surfaceDestroyed()、surfaceChanged()可以创建/释放某些资源。下面这个地方需要注意一下:

videoWidth = mediaPlayer.getVideoWidth(); videoHeight = mediaPlayer.getVideoHeight(); if (videoHeight != 0 && videoWidth != 0) { arg0.start(); }

有些视频是android播放器不能播放的,不能播放时videoHeight=0,videoWidth=0,以此来判断是否播放视频。

Player.java源码如下:

package com.videoplayer; import java.io.IOException; import java.util.Timer; import java.util.TimerTask; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaPlayer.OnBufferingUpdateListener; import android.media.MediaPlayer.OnCompletionListener; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.widget.SeekBar; public class Player implements OnBufferingUpdateListener, OnCompletionListener, MediaPlayer.OnPreparedListener, SurfaceHolder.Callback { private int videoWidth; private int videoHeight; public MediaPlayer mediaPlayer; private SurfaceHolder surfaceHolder; private SeekBar skbProgress; private Timer mTimer=new Timer(); public Player(SurfaceView surfaceView,SeekBar skbProgress) { this.skbProgress=skbProgress; surfaceHolder=surfaceView.getHolder(); surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); mTimer.schedule(mTimerTask, 0, 1000); } /******************************************************* * 通过定时器和Handler来更新进度条 ******************************************************/ TimerTask mTimerTask = new TimerTask() { @Override public void run() { if(mediaPlayer==null) return; if (mediaPlayer.isPlaying() && skbProgress.isPressed() == false) { handleProgress.sendEmptyMessage(0); } } }; Handler handleProgress = new Handler() { public void handleMessage(Message msg) { int position = mediaPlayer.getCurrentPosition(); int duration = mediaPlayer.getDuration(); if (duration > 0) { long pos = skbProgress.getMax() * position / duration; skbProgress.setProgress((int) pos); } }; }; //***************************************************** public void play() { mediaPlayer.start(); } public void playUrl(String videoUrl) { try { mediaPlayer.reset(); mediaPlayer.setDataSource(videoUrl); mediaPlayer.prepare();//prepare之后自动播放 //mediaPlayer.start(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void pause() { mediaPlayer.pause(); } public void stop() { if (mediaPlayer != null) { mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { Log.e("mediaPlayer", "surface changed"); } @Override public void surfaceCreated(SurfaceHolder arg0) { try { mediaPlayer = new MediaPlayer(); mediaPlayer.setDisplay(surfaceHolder); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setOnBufferingUpdateListener(this); mediaPlayer.setOnPreparedListener(this); } catch (Exception e) { Log.e("mediaPlayer", "error", e); } Log.e("mediaPlayer", "surface created"); } @Override public void surfaceDestroyed(SurfaceHolder arg0) { Log.e("mediaPlayer", "surface destroyed"); } @Override /** * 通过onPrepared播放 */ public void onPrepared(MediaPlayer arg0) { videoWidth = mediaPlayer.getVideoWidth(); videoHeight = mediaPlayer.getVideoHeight(); if (videoHeight != 0 && videoWidth != 0) { arg0.start(); } Log.e("mediaPlayer", "onPrepared"); } @Override public void onCompletion(MediaPlayer arg0) { // TODO Auto-generated method stub } @Override public void onBufferingUpdate(MediaPlayer arg0, int bufferingProgress) { skbProgress.setSecondaryProgress(bufferingProgress); int currentProgress=skbProgress.getMax()*mediaPlayer.getCurrentPosition()/mediaPlayer.getDuration(); Log.e(currentProgress+"% play", bufferingProgress + "% buffer"); } }

test_videoplayer.java是主程序,负责调用Player类,其中关键部分是SeekBarChangeEvent这个SeekBar拖动的事件:SeekBar的Progress是0~SeekBar.getMax()之内的数,而MediaPlayer.seekTo()的参数是0~MediaPlayer.getDuration()之内数,所以MediaPlayer.seekTo()的参数是(progress/seekBar.getMax())*MediaPlayer.getDuration()。

test_videoplayer.java源码如下:

package com.videoplayer; import android.app.Activity; import android.content.pm.ActivityInfo; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.SurfaceView; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.SeekBar; public class test_videoplayer extends Activity { private SurfaceView surfaceView; private Button btnPause, btnPlayUrl, btnStop; private SeekBar skbProgress; private Player player; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); surfaceView = (SurfaceView) this.findViewById(R.id.surfaceView1); btnPlayUrl = (Button) this.findViewById(R.id.btnPlayUrl); btnPlayUrl.setOnClickListener(new ClickEvent()); btnPause = (Button) this.findViewById(R.id.btnPause); btnPause.setOnClickListener(new ClickEvent()); btnStop = (Button) this.findViewById(R.id.btnStop); btnStop.setOnClickListener(new ClickEvent()); skbProgress = (SeekBar) this.findViewById(R.id.skbProgress); skbProgress.setOnSeekBarChangeListener(new SeekBarChangeEvent()); player = new Player(surfaceView, skbProgress); } class ClickEvent implements OnClickListener { @Override public void onClick(View arg0) { if (arg0 == btnPause) { player.pause(); } else if (arg0 == btnPlayUrl) { String url="http://daily3gp.com/vids/family_guy_penis_car.3gp"; player.playUrl(url); } else if (arg0 == btnStop) { player.stop(); } } } class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener { int progress; @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { // 原本是(progress/seekBar.getMax())*player.mediaPlayer.getDuration() this.progress = progress * player.mediaPlayer.getDuration() / seekBar.getMax(); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { // seekTo()的参数是相对与影片时间的数字,而不是与seekBar.getMax()相对的数字 player.mediaPlayer.seekTo(progress); } } }

感兴趣的读者可以自己动手测试一下本文实例代码,相信对大家进行Android程序开发有一定的借鉴作用。

时间: 2024-10-28 03:03:28

Android提高之MediaPlayer播放网络视频的实现方法的相关文章

Android提高之MediaPlayer播放网络视频的实现方法_Android

前面讲解了MediaPlayer播放网络音频,主要介绍了MediaPlayer关于网络音频的缓冲和进度条控制的方法,本文再来讲解一下MediaPlayer播放网络视频的方法.播放网络视频比播放网络音频需要多一个SurfaceView而已,在已经熟悉了MediaPlayer播放网络音频之后,相信大家对本文所述的播放网络视频也能很快地掌握. 先来看看本文程序运行截图,如下所示: 本文程序的视频来自http://daily3gp.com,大家可以替换程序中的视频链接,试试其他影片. main.xml的

Android提高之MediaPlayer播放网络音频的实现方法_Android

前面有文章曾经地介绍过MediaPlayer的基本用法,这里就更加深入地讲解MediaPlayer的在线播放功能.本文主要实现MediaPlayer在线播放音频的功能,由于在线视频播放比在线音频播放复杂,因此先介绍在线音频播放的实现,这样可以帮助大家逐步深入了解MediaPlayer的在线播放功能. 先来看看本文程序运行的结果如下图所示: main.xml的源码如下: <?xml version="1.0" encoding="utf-8"?> <

android 用mediaplayer播放网络视频如何抓图,任意时间的抓取?

问题描述 本人最近在做一个视频监控的项目,需要在客户端抓图,但因为是网络实时图像,用传统的Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(filePath, Thumbnails.MINI_KIND);方式,抓到的bitmap 是null,但抓取SD卡上现有的视频可以得到一个缩略图,但此方式不可任意指定时间抓取图片. 不知各位大侠有这方面经验没有,希望得到一些解决思路! 问题补充:shaobin0604 写道 解决方案 方法1: 读取 fr

android 非ophone系统,在cmwap播放网络视频,url改怎么写参数

问题描述 android非ophone系统,在cmwap播放网络视频,url改怎么写参数谢谢 解决方案 解决方案二:该回复于2010-05-18 16:20:52被版主删除解决方案三:HttpPosthttpRequest=newHttpPost(url);//Post运作传送变数必须用NameValuePair[]阵列储存//传参数服务端获取的方法为request.getParameter("name")List<NameValuePair>params=newArray

wps演示教程:妙用控件工具在幻灯片里播放网络视频

运用之妙 存乎一心 --妙用控件工具在幻灯片里播放网络视频 伴随着网络带宽的不断提高,视频点播已经成为互联网的主流娱乐项目之一.在海量的网络视频里有许多优质的教学素材.使用常规方法插入网络视频至少要解决两个难题:一是网络视频的下载,但让人无奈的是,越来越多的网站开始对视频资源进行技术加密,普通用户难以下载使用;二是视频格式的转换,因为网络视频多为 rmvb.Flv.f4v等流媒体格式,WPS演示不支持这些格式的视频,必须使用格式工厂等第三方软件将其转为wmv格式后方可插入. 那么,可否将这些优质

Word2013如何播放网络视频

Word2013播放网络视频的步骤 新版Word中支持在内部程序直接搜索主流视频网站内容,包括通过Bing搜索和Youtube上输入关键词进行搜索,当然你也可以直接复制视频的嵌入式代码到Word里面. 文档加视频播放"> 当通过上面搜索出来的时候都会以小字预览的方式进行排列,选择插入或者点击右边的图标可以跳转到Youtube等搜索出来的网站进行观看.当然如果你已经在视频网站上找到相关的资源的话,也可以通过复制嵌入式代码插入到Word中来. 插入的视频可以向图片一样进行编辑,你可以按照各种形

MPMoviePlayerController播放网络视频的缓存目录

问题描述 MPMoviePlayerController播放网络视频的缓存目录 由于项目需要,播放网络视频我调用了MPMoviePlayerController,后面我想做缓存处理时,发现它在播放网络视频时下面显示了下载进度条,貌似已经下载下来了,我现在就是需要找到下载的目录.劳烦大神告知一下. 解决方案 关于MPMoviePlayerController以及MPMoviePlayerViewControlle流媒体视频播放

本地-如何获取mediaplayer播放网络音频时的缓存?

问题描述 如何获取mediaplayer播放网络音频时的缓存? 如题:做一款音乐播放器,如何取出网络音频的缓存呢?mediaplayer貌似是取不出来了, audiotrack貌似可以,但是不知道怎么做,大家有什么方法么?其实我就是想播放过一次 的音频可以缓存到本地,下次播放的时候可以不用再次去请求网络数据流,去缓存了

MX Player怎么播放网络视频 MX播放器看网络视频方法

1.打开MX Player播放器APP后,点击右上角[···] 2.在弹出层中选择[网络流] 3.在地址栏中输入带视频格式的网址后点击[确定] 4.如果网址有效即可开始播放. 以上就是MX play播放器播放网络视频的步骤介绍,需要注意的是网络视频地址必须带有视频格式文件的后缀名才行哦.