---------------------- <a href="http://edu.csdn.net/heima" target="blank">android培训</a>、<a href="http://edu.csdn.net/heima" target="blank">java培训</a>、期待与您交流! ----------------------
好的,今天从14:01开始学习:
1.经过了一段假期的休息,现在又要重新开始学习了,先来复习一下上次的学习要点:
好的,花了一个多小时终于将音乐播放器写完了,我们接着来学习新的知识要点。
2.好的,接下来我们通过android中的多媒体接口呢,来实现一个视频播放器。
我们要开发的视频播放器的软件界面是这样的:
来创建这个android工程VideoPlayer:
然后点击完成。
先来设计一下软件的界面:
注意这边要用到四个图片按钮。
我们要把应用中用到的图片放到res目录底下。
注意图片文件不要带上什么.png,.jpeg
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/filename" />
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/filename"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/play"
android:onClick="mediaplay"
android:id="@+id/play"
/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/pause"
android:onClick="mediaplay"
android:id="@+id/pause"
/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/reset"
android:onClick="mediaplay"
android:id="@+id/reset"
/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/stop"
android:onClick="mediaplay"
android:id="@+id/stop"
/>
</LinearLayout>
</LinearLayout>
3.再来看看下面那个显示视频文件的界面:
这个控件叫做SurfaceView
这个控件是专门用来绘图的,比如以后我们要在界面上画图,画圆啊,都可以通过它。
<SurfaceView
android:layout_width="fill_parent"
android:layout_height="240dp"
android:id="@+id/video"
/>
4.我们来在activity中完成四个按钮的代码:
package cn.itcast.videoplayer;
import java.io.File;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.EditText;
public class VideoPlayerActivity extends Activity {
private String path;
private MediaPlayer mediaPlayer;
private SurfaceView video;//将其定义在成员变量中,虽然要在初始化方法中初始化,但是必须要在成员变量中定义后面才可以使用
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
video=(SurfaceView)this.findViewById(R.id.video);
mediaPlayer=new MediaPlayer();//因为后面要用到,所以我们在初始化方法里面实例化媒体对象
}
protected void onDestroy() {
mediaPlayer.release();
mediaPlayer=null;
super.onDestroy();
}
public void videoplay(View v){
EditText nameText=(EditText)findViewById(R.id.filename);
String filename=nameText.getText().toString();
File video=new File(Environment.getExternalStorageDirectory(),filename);
switch(v.getId()){
case R.id.play:
if(video.exists()){
path=video.getAbsolutePath();
play();
}
break;
case R.id.pause:
break;
case R.id.reset:
break;
case R.id.stop:
break;
}
}
private void play() {
try {
mediaPlayer.reset();//由于后面我们肯还要用到重播,所以我们呢将播放器的各项参数恢复到初始状态
mediaPlayer.setDataSource(path);
//设置视频的画面输出到什么位置,这个和音乐播放器有点区别
mediaPlayer.setDisplay((SurfaceHolder) video);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
5.我们在使用SurfaceView这个显示控件的时候,要给它设置一些参数:
package cn.itcast.videoplayer;
import java.io.File;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.EditText;
public class VideoPlayerActivity extends Activity {
private String path;
private MediaPlayer mediaPlayer;
private SurfaceView video;//将其定义在成员变量中,虽然要在初始化方法中初始化,但是必须要在成员变量中定义后面才可以使用
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mediaPlayer=new MediaPlayer();
video=(SurfaceView)this.findViewById(R.id.video);
//把输送给surfaceview的视频画面直接显示到屏幕上,不要维护它自身的缓冲区
video.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
//设置它要显示的视频画面的分辨率
video.getHolder().setFixedSize(176, 144);
//还有设置在视频播放的时候,手机不要锁屏
video.getHolder().setKeepScreenOn(true);//设置完之后,我们就要将surfaceview的控对象也就是getHolder()传进去
}
protected void onDestroy() {
mediaPlayer.release();
mediaPlayer=null;
super.onDestroy();
}
public void videoplay(View v){
EditText nameText=(EditText)findViewById(R.id.filename);
String filename=nameText.getText().toString();
File video=new File(Environment.getExternalStorageDirectory(),filename);
switch(v.getId()){
case R.id.play:
if(video.exists()){
path=video.getAbsolutePath();
play();
}
break;
case R.id.pause:
break;
case R.id.reset:
break;
case R.id.stop:
break;
}
}
private void play() {
try {
mediaPlayer.reset();//由于后面我们肯还要用到重播,所以我们呢将播放器的各项参数恢复到初始状态
mediaPlayer.setDataSource(path);
//设置视频的画面输出到什么位置,这个和音乐播放器有点区别
mediaPlayer.setDisplay(video.getHolder());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
6.继续做:
package cn.itcast.videoplayer;
import java.io.File;
import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.os.Environment;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class VideoPlayerActivity extends Activity {
private String path;
private MediaPlayer mediaPlayer;
private SurfaceView video;//将其定义在成员变量中,虽然要在初始化方法中初始化,但是必须要在成员变量中定义后面才可以使用
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mediaPlayer=new MediaPlayer();
video=(SurfaceView)this.findViewById(R.id.video);
//把输送给surfaceview的视频画面直接显示到屏幕上,不要维护它自身的缓冲区
video.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
//设置它要显示的视频画面的分辨率
video.getHolder().setFixedSize(176, 144);
//还有设置在视频播放的时候,手机不要锁屏
video.getHolder().setKeepScreenOn(true);//设置完之后,我们就要将surfaceview的控对象也就是getHolder()传进去
}
protected void onDestroy() {
mediaPlayer.release();
mediaPlayer=null;
super.onDestroy();
}
public void videoplay(View v){
EditText nameText=(EditText)findViewById(R.id.filename);
String filename=nameText.getText().toString();
File video=new File(Environment.getExternalStorageDirectory(),filename);
switch(v.getId()){
case R.id.play:
if(video.exists()){
path=video.getAbsolutePath();
play();
}else{
Path=null;
Toast.makeText(getApplicationContext(),R.string.filenoexsit, Toast.LENGTH_LONG).show();
}
break;
case R.id.pause:
break;
case R.id.reset:
break;
case R.id.stop:
break;
}
}
private void play() {
try {
mediaPlayer.reset();//由于后面我们肯还要用到重播,所以我们呢将播放器的各项参数恢复到初始状态
mediaPlayer.setDataSource(path);
//设置视频的画面输出到什么位置,这个和音乐播放器有点区别
mediaPlayer.setDisplay(video.getHolder());
mediaPlayer.prepare();
mediaPlayer.setOnPreparedListener(new PreparedListener());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private final class PreparedListener implements OnPreparedListener{
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();//播放视频
}
}
}
7.来处理暂停按钮:
case R.id.pause:
if(mediaPlayer.isPlaying()){//如果视频是播放着的
mediaPlayer.pause();
pause=true;
}else{
if(pause){//如果视频是暂停的
mediaPlayer.start();//注意,这里是继续播放视频
pause=false;
}
}
break;
再来处理重播按钮:
case R.id.reset:
if(mediaPlayer.isPlaying()){
mediaPlayer.seekTo(0);
}else{
if(path!=null){
play();
}
}
break;
最后写停止按钮:
case R.id.stop:
if(mediaPlayer.isPlaying()){
mediaPlayer.stop();
}
break;
8.代码已写完了,接下来我们要来测试了。
大家有没有看到这个surfaceview显示控件,没有,因为这个控件默认是黑色的,和背景色一样。
现在我们把背景色改一下:
回到主界面,白色是#FFFFFF:
android:background="#FFFFFF"
重新部署一下,然后就可以看到那个显示控件,接着导入一个视频到SD卡里面。
我们看看能不能显示出来,能不能动。
我们点一下播放按钮,画面没有出现。为什么呢?
采用android2.2或者2.1模拟器它是出现不了画面的。
这是模拟器的问题。
要测试它呢,要采用android2.0模拟器才可以显示,但是在手机上不会出现这种情况。
9.我们新建一个android2.0模拟器!
注意,我们要对我们的android工程进行版本的策换,换成android2.0
还有在清单文件中将版本改为5,也就是2.0.
可以了,再点击暂停,再点击重播,再点击停止。这些功能都可以实现!
10.好的,接下来我们再来测试一种情况:
如果正在播放视频,然后来了一个电话,那么这个视频和电话和视频会同时进行,所以要解决这个问题。
用到activity的生命周期。
protected void onPause() {
if(mediaPlayer.isPlaying()){
//正在播放的话,先取得当前的播放位置
position=mediaPlayer.getCurrentPosition();
mediaPlayer.stop();
}
super.onPause();
}
protected void onResume() {
if(position>0&&path!=null){
play();
mediaPlayer.seekTo(position);
position=0;
}
super.onResume();
}
再来观察一下,可以了当电话到来的时候,视频停止了,然后回到前台,又开始继续播放。
但是此时,声音是在继续播放,但是画面没有继续。
11.这是由于什么原因呢?
这个原因很重要,以后字在使用surfaceview显示控件的时候,经常用到。
不管你以后是用它来做视频播放器还是画图,都要了解。
当surfaceview所在的activity离开了前台,surfaceview会被摧毁。当activity又重新回到前台时,surfaceview会被重新创建。Surfaceview是在onResume()方法之后被创建。也就是说,当电话来了,这个activity也就不在前台了,Surfaceview会被摧毁,当电话被挂断,这个应用重新回到前台,surfaceview会被重新创建,它是在onResume()之后被创建的。所以此时画面不会出来,因为surfaceview还没开始被创建。
那么怎么解决这个问题呢,我们必须在surfaceview被创建出来之后才能恢复视频的播放。
12.目前我们的视频播放器它只能播放本地的视频,如果要播放互联网上的视频,这样,我们把我们要播放的视频放在这个web应用中。放在web应用的根目录底下,也就是webroot目录下。
然后将这个web应用部署到tomcat中。
部署上去之后,我们就可以在播放器输入视频文件的地址。
当然,我们要访问网络文件,就必须在清单文件中,加上一个网络访问权限。
然后再把视频播放器安装到模拟器上,注意要访问web文件,先要部署web服务器。
好的,我们点击播放。大家看看能否播放网络上的视频文件,当然我们的代码是不是要改造一下啊:
public void videoplay(View v){
EditText nameText=(EditText)findViewById(R.id.filename);
String filename=nameText.getText().toString();
if(filename.startsWith("http")){//如果文件名是以http开头的话,代表播放网络文件
path=filename;
play();
}else{
File video=new File(Environment.getExternalStorageDirectory(),filename);
switch(v.getId()){
case R.id.play:
if(video.exists()){
path=video.getAbsolutePath();
play();
}else{
path=null;
Toast.makeText(getApplicationContext(),R.string.filenoexsit, Toast.LENGTH_LONG).show();
}
break;
13.完成之后,把应用部署到android2.0模拟器上。
还是没有任何反应。
因为代码里面的play()出错了,通过这个api好像是无法播放互联网上的视频。
为什么呢?主要的原因是因为这个视频文件不属于流媒体文件,如果要播放互联网上的视频,必须是流媒体类型的。
流媒体分发方式:
渐进式下载和实时流媒体。
而渐进式下载需要web服务器来分发。
所以你要播放通过http协议分发的视频文件,那么这个视频文件必须是渐进式的。
现在要利用一个工具,把这个视频文件转换一下格式,转换成渐进式下载视频。
一款什么工具呢,quicktime!
这个软件既可以播放视频,又可以编辑视频。
打开这款软件:
这个软件是经过破解的专业版。
再点击选项:
视频格式H263或者H264,但是H263要好很多。
注意是3G网络。
数据速率要根据你3G网络的带宽来设置,越高画质越清晰,但是是不是越高就越好呢?不是,这个速率一定要与你网络带宽的速率匹配上。如果你这个视频的带宽高于你的网络带宽,否则会播放不出来,但是也不能太低,那样视频太模糊,所以建立这个数据速率不要超过230,高于160.160-230,一般是180.
最后,点击确定。最后导出!
接着把导出的文件放到web应用中,然后部署web应用,最后在模拟器中访问该文件:
成功了!
以前做在线视频播放是怎么做的呢,把一个大视频分割成很多个小视频,然后将它们下载到本地中播放。就实现了一个类似在线视频播放的效果,但不是真正在线视频播放,而这个是真正的在线播放。只要知道如何转换成渐进式视频,其他代码和本地视频播放差不多!
今天学完了视频44,学习了4个小时!可以做做JAVA习题,android教程10天以内学完。然后学完之后,开始全面复习java和做java习题,如果在一个月内弄完了,剩下的时间可以再复习一下javaweb.最后一个月学习数据库!每天保证4小时的学习时间,一个礼拜学习5次!
---------------------- <a href="http://edu.csdn.net/heima" target="blank">android培训</a>、<a href="http://edu.csdn.net/heima" target="blank">java培训</a>、期待与您交流! ----------------------