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

黑马程序员-android视频播放器相关推荐

  1. 黑马程序员—[Android就业薪资] Android30期,毕业37工作日,就业率93%,平均薪水10315元!

    文章来源:黑马程序员,黑马论坛 Android30期,毕业37工作日,就业率93%,平均薪水10315 元! 毕业班级:黑马程序员Android30期 毕业时间:7月2日 总人数:72人 班     ...

  2. 黑马程序员—[Android就业薪资] Android31期,毕业18个工作日,就业率71.95%,薪资9946元

    文章来源:黑马程序员,黑马论坛. Android31期,毕业18个工作日,就业59人,平均薪资9946元 毕业班级:黑马程序员Android31期 毕业时间:7月22日 总人数:82人 班       ...

  3. 黑马程序员—[Android就业薪资] Android28期,毕业60天,就业率96.15%,平均薪水9378元!

    文章来源:黑马程序员,黑马论坛 Android28期,毕业60天,就业率96.15%,平均薪水9378元! 班级名称:黑马Android28期   毕业时间:2014年5月22日      总人数:7 ...

  4. 黑马程序员Android学习笔记——金山卫士项目——第三天

    学习了,一定要总结,学习贵在永恒贵在用心. 学习内容: 1.绑定sim卡 2.检查手机是否更换sim卡 3.读取手机联系人 4.手机防盗原理 5.短信指令的广播 6.播放报警音乐 7.三种获取手机位置 ...

  5. 黑马程序员————高新技术————类加载器

    ----------------------ASP.Net+Android+IOS开发----------------------期待与您交流! 类加载器 Java虚拟机中可以安装多个类的加载器,系统 ...

  6. 黑马程序员Android学习笔记——金山卫士项目——第四天

    主要学习内容: 1)号码归属地查询UI设计 2)号码归属地查询的原理 3)号码归属地查询的代码实现 5)输入框抖动和震动效果 6)来电.去电号码归属地的显示 7)代码注册广播接受者的实现 8)自定义吐 ...

  7. 《黑马程序员Android移动应用基础教程》学习笔记(2)

    文章目录 Ch 2 Android常见界面布局 2.1 View视图 2.2 界面布局编写方式 2.2.1 在XML文件中编写布局 2.2.2 在Java代码中编写布局 2.3 常见界面布局 2.3. ...

  8. 黑马程序员___java类加载器

    -----------android培训.java培训.java学习型技术博客.期待与您交流! --------- 类加载器基本概念 顾名思义,类加载器(class loader)用来加载 Java ...

  9. 黑马程序员Android学习笔记——金山卫士项目——第二天

    这几天学习了第二天的内容, 项目源代码:http://download.csdn.net/detail/itjavawfc/8241695 主要收获了: 1)自定义属性:一般用在组合控件中 2)自定义 ...

  10. 《Android移动应用基础教程》(Android Studio)(第二版)黑马程序员 课后习题答案

    <Android移动应用基础教程>(Android Studio)(第二版)黑马程序员 课后习题答案 目录 第1章 Android基础入门 第2章 Android常见界面布局 第3章 An ...

最新文章

  1. 字符串相加 java_字符串相加-LeetCode(Java实现)
  2. [MySQL基础]数据库存储数据的特点
  3. 为什么要编写单元测试–测试技巧8
  4. spark计算操作整理
  5. H5炫酷特效系列3——瀑布流水特效
  6. GIT : IDEA切换到某个tag
  7. 对领域驱动设计的理解与实践
  8. 【实例解析】某集团BI决策系统建设方案分享
  9. 三菱fx3u中文手册_3个月高效掌握三菱PLC!四个阶段经验大总结~
  10. PHPCMS 模板标签
  11. python发音1001python发音-怎样才能写出 Pythonic 的代码 #P1001#
  12. spring boot 教程(三)配置详解
  13. [算法]用Python实现十大排序算法
  14. 【智能家居v1.0项目】C#实现scoket通信
  15. JDK安装包和Mysql安装包整理
  16. Python 的切片为什么不会索引越界?
  17. 如何用保险保障自己的一生?
  18. 敢不敢用一年时间改变你自己?
  19. 上瘾啦,又用 Python 制作销售数据可视化看板
  20. 2021年微软研究博士奖研金名单出炉!三位华人博士生入选,每人42000美元

热门文章

  1. 海康GB28181接入SRS服务器,实现低延迟直播
  2. Windows API一日一练(69)GetTickCount函数
  3. 微信小程序:强大的多功能图片处理器
  4. 【Verilog】移位寄存器总结:移位寄存器、算数移位寄存器、线性反馈移位寄存器(LFSR)
  5. Python学习插曲之万年历算法
  6. 尝试OUTFIle、INFILE快速导入导出数据
  7. 计算机组成flash小游戏,flash小游戏动画制作步骤(带源文件)
  8. 如何将音乐上传到YouTube音乐
  9. 仿微信图片选取、相机拍照—PhotoPicker(已集成GalleryView)
  10. Sentinel 流控规则,降级规则(服务熔断),热点key 限流,系统规则 ,持久化。 超详细讲解