本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处!
上次讲解了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开发ExoPlayer播放视频和wav音频"这个主题,我们将深入探讨如何在Android应用中集成和使用ExoPlayer来播放视频和.wav音频文件。 首先,要添加ExoPlayer库到项目中,我们需要在build.gradle文件的...
1. **MediaPlayer类**:Android系统提供了`MediaPlayer`类,它是处理音频和视频播放的核心组件。在在线播放音频时,我们首先需要创建`MediaPlayer`实例,然后设置数据源为网络URL,最后调用`prepare()`或`...
在Android平台上实现在线播放音频和视频是一项常见的任务,尤其在移动应用开发中。这个主题涉及到多个技术点,包括网络请求、多媒体数据处理、播放器组件的使用等。下面将详细探讨这些关键知识点。 首先,我们需要...
在Android平台上,音频和视频播放是移动应用开发中不可或缺的一部分。Android Media API为开发者提供了强大的工具,用于处理各种媒体文件的播放、录制和处理。在这个主题中,我们将深入探讨Android中的音频和视频...
首先,MediaPlayer是Android SDK提供的一个类,它可以播放本地或网络上的音频和视频资源。在Android应用中,使用MediaPlayer的基本步骤包括初始化、设置数据源、准备和开始播放。例如,初始化一个MediaPlayer对象,...
在Android平台上,音频和视频的播放是移动应用开发中不可或缺的一部分。本文将深入探讨如何在Android中使用不同的组件和技术来实现音频和视频的播放功能,包括`MediaPlayer`媒体播放器、`SoundPool`音效池以及`...
MediaPlayer是Android系统提供的一个核心组件,它可以处理各种音频和视频格式的播放。对于本地MP3文件,我们通常将其放在res/raw目录下,因为这个目录下的资源文件会被编译进APK,方便直接访问。 1. 创建...
Android网络视频播放器是一种常见的移动应用,它允许用户通过互联网流式传输和播放视频内容。这个“android网络视频播放器(完整可运行).zip”压缩包包含了实现此类功能所需的关键组件和资源。下面我们将深入探讨...
1. **Media Player API**:Android系统提供了MediaPlayer类,它是系统级别的多媒体播放器,支持音频和视频播放。开发者可以通过创建MediaPlayer对象,加载视频资源,设置播放状态,并处理播放事件。 2. **...
在Android平台上开发在线视频和音频应用是一项常见的任务,尤其在当今移动互联网时代,实时通信(RTC)技术在社交、教育、远程工作等多个领域都扮演着重要角色。标题中提到的项目是一个基于Android的在线视频和音频...
1. 音频文件(我在这里使用的是mp3格式的)的播放,暂停,停止。 2. 音频文件的时长显示(还未加载完成的音频) 3. 简单的音频播放计时功能 4. 清楚缓存 5. 自动读取缓存文件(没有缓存从网络读取,有缓存的时候...
本文将深入探讨“android网络播放视频源码”这一主题,讲解如何实现这个功能,以及涉及的关键技术点。 首先,Android系统提供了一些核心组件来支持网络视频播放,主要包括`MediaPlayer`和`ExoPlayer`。`MediaPlayer...
1. 首先,我们需要获取到网络视频的URL。这通常是一个HTTP或HTTPS链接,例如:`https://example.com/video.mp4`。 2. 创建`MediaPlayer`实例,并调用`setDataSource()`方法传入URL。注意,由于网络请求可能涉及异步...
在Android平台上,开发一款能够播放网络视频的播放器是一项常见的任务。这个名为"android播放器,可以播放网络视频"的项目就是基于IJK框架实现的,它不仅支持在线流媒体播放,还能处理本地视频文件,提供了丰富的...
在Android平台上,实现在线播放功能是一项常见的需求,无论是视频流媒体服务还是音频串流应用,都需要处理网络数据的实时解码和播放。本教程将深入探讨如何在Android中实现在线播放,包括本地播放和在线播放的技术...
2. **媒体播放器组件**:Android系统提供了一个名为`MediaPlayer`的类,用于播放音频和视频。在这个Demo中,`MediaPlayer`被用来接收来自海康摄像头的视频流,并将其在Android设备上显示出来。开发者需要配置`...
libvlc是一个跨平台的库,它提供了一个底层的多媒体框架,能够解码、播放和控制各种音频和视频格式,包括但不限于MPEG、H.264、AAC等。此外,它还支持RTSP、HTTP、FTP等网络流媒体协议,以及从本地文件、网络流、DVD...
MediaPlayer是Android提供的媒体播放类,它可以播放本地文件、网络流媒体以及Android资源中的音频和视频。在我们的示例中,它主要负责加载音频文件并控制播放、暂停、停止等操作。 2. **初始化MediaPlayer**: 在...
在博客"Android使用MediaPlayer播放视频"中,作者更详细地介绍了如何实现视频播放,包括网络视频播放、处理播放状态变化、控制播放进度等功能。通过阅读该博客,你可以获得更全面的了解和实践指导。 总之,`...
Android 6.0引入了运行时权限管理,这对视频播放库来说意味着需要适当地请求和处理用户对存储和网络访问的权限。而Android 7.0优化了后台运行限制,对多媒体应用的性能和电池续航有所提升,同时支持更高效的多任务...