黑马程序员-android视频播放器

---------------------- <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>、期待与您交流! ----------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值