package cn.c;
import java.io.File;
import java.io.IOException;
import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.os.Bundle;
import android.os.Environment;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.LinearLayout;
public class MainActivity extends Activity implements
OnCompletionListener,OnErrorListener,OnInfoListener,OnPreparedListener,
OnSeekCompleteListener,OnVideoSizeChangedListener,SurfaceHolder.Callback{
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private Display mDisplay;
private MediaPlayer mMediaPlayer;
int videoWidth=0;
int videoHeight=0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mDisplay=getWindowManager().getDefaultDisplay();
mSurfaceView=(SurfaceView) findViewById(R.id.surfaceView);
mSurfaceHolder=mSurfaceView.getHolder();
//SurfaceHolder是用于管理SurfaceView对象
//那它是怎么做到管理的呢?即用mSurfaceHolder
//添加回调即addCallback.
//该类实现了SurfaceHolder.Callback接口,所以addCallback(this)
//在SurfaceHolder.Callback接口中一共有三个方法来实现对于
//SurfaceView对象的管理,即:
//surfaceCreated()
//surfaceChanged()
//surfaceDestroyed()
//概况:SurfaceHolder主要作用是监控底层的情况
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mMediaPlayer=new MediaPlayer();
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnErrorListener(this);
mMediaPlayer.setOnInfoListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setOnSeekCompleteListener(this);
mMediaPlayer.setOnVideoSizeChangedListener(this);
String path=Environment.getExternalStorageDirectory().getPath()
+File.separator+"Test_Movie.m4v";
try {
//设置MediaPlayer将要播放的视频
mMediaPlayer.setDataSource(path);
} catch (IllegalArgumentException e) {
e.printStackTrace();
finish();
} catch (IllegalStateException e) {
e.printStackTrace();
finish();
} catch (IOException e) {
e.printStackTrace();
finish();
}
}
//来自于SurfaceHolder.Callback接口
//创建SurfaceView完成时,会调用该方法
public void surfaceCreated(SurfaceHolder holder) {
//设置MediaPlayer的视频输出界面
//只显示音频而不显示视频时可不调用这个方法
mMediaPlayer.setDisplay(mSurfaceHolder);
try {
//准备播放,调用mMediaPlayer.prepareAsync();
//方法后会执行覆写后的
//public void onPrepared(MediaPlayer mp)
//注意:
//也可调用prepare()解码,但为一个同步的操作
mMediaPlayer.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
finish();
}
}
//来自于SurfaceHolder.Callback接口
//当SurfaceView的宽度,高度或其他参数发生变化时,会调用该方法
public void surfaceChanged(SurfaceHolder holder,
int format, int width,int height) {
}
//来自于SurfaceHolder.Callback接口
//当SurfaceView摧毁时,会调用该方法
public void surfaceDestroyed(SurfaceHolder holder) {
}
//来自于MediaPlayer.OnVideoSizeChangedListener接口
//当视频的宽度或高度发生变化时调用该方法
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
}
//来自于MediaPlayer.OnSeekCompleteListener接口
public void onSeekComplete(MediaPlayer mp) {
}
//来自于MediaPlayer.OnPreparedListener接口
//一旦调用该方法,MediaPlayer就进入了"准备就绪"
//状态,准备开始播放.
//此处可用于动态设置SurfaceView的宽和高!!!
public void onPrepared(MediaPlayer mediaPlayer) {
videoWidth=mediaPlayer.getVideoWidth();
videoHeight=mediaPlayer.getVideoHeight();
if (videoWidth > mDisplay.getWidth()|| videoHeight > mDisplay.getHeight()) {
float heightRatio = (float) videoHeight/ (float) mDisplay.getHeight();
float widthRatio = (float) videoWidth/ (float) mDisplay.getWidth();
if (heightRatio > 1 || widthRatio > 1) {
if (heightRatio > widthRatio) {
videoHeight = (int) Math.ceil((float) videoHeight/ (float) heightRatio);
videoWidth = (int) Math.ceil((float) videoWidth/ (float) heightRatio);
} else {
videoHeight = (int) Math.ceil((float) videoHeight/ (float) widthRatio);
videoWidth = (int) Math.ceil((float) videoWidth/ (float) widthRatio);
}
}
}
//设置SurfaceView的宽和高
mSurfaceView.setLayoutParams
(new LinearLayout.LayoutParams(videoWidth,videoHeight));
//MediaPlayer开始播放
mediaPlayer.start();
}
//来自于MediaPlayer.OnInfoListener接口
//当出现关于播放媒体的特定信息或者需要发出警告的时候
//将调用该方法
//比如开始缓冲、缓冲结束、
下载速度变化(该行待验证)
//小结:这些Info都是以MediaPlayer.MEDIA_INFO_开头的
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what==MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING) {
//音频和视频数据不正确地交错时将出现该提示信息.在一个
//正确交错的媒体文件中,音频和视频样本将依序排列,从而
//使得播放可以有效和平稳地进行
}
if (what==MediaPlayer.MEDIA_INFO_NOT_SEEKABLE) {
//当媒体不能正确定位时将出现该提示信息.
//此时意味着它可能是一个在线流
}
if (what==MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING) {
//当设备无法播放视频时将出现该提示信息
//比如视频太复杂或者码率过高
}
if (what==MediaPlayer.MEDIA_INFO_METADATA_UPDATE) {
//当新的元数据可用时将出现该提示信息
}
if (what==MediaPlayer.MEDIA_INFO_UNKNOWN) {
//其余不可知提示信息
}
return false;
}
//来自于MediaPlayer.OnErrorListener接口
//MediaPlayer发生错误时会调用该方法
//只有如下这三种错误.
//小结:这些错误都是以MediaPlayer.MEDIA_ERROR.开头的
public boolean onError(MediaPlayer mp, int what, int extra) {
if (what==MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {
System.out.println("第一种错误");
}
if (what==MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
System.out.println("第二种错误");
}
if (what==MediaPlayer.MEDIA_ERROR_UNKNOWN) {
System.out.println("第三种错误");
}
return false;
}
//来自于MediaPlayer.OnCompletionListener接口
//当MediaPlayer播放完文件时,会调用该方法.
//此时可以进行一些其他的操作比如:播放下一个视频
public void onCompletion(MediaPlayer mp) {
finish();
}
}
- Android 播放视频文件
package com.example.myvideo2; import java.io.File; import android.app.Activity; import android.net.U ...
- android: 播放视频
播放视频文件其实并不比播放音频文件复杂,主要是使用 VideoView 类来实现的.这个 类将视频的显示和控制集于一身,使得我们仅仅借助它就可以完成一个简易的视频播放器. VideoView 的用法和 ...
- Android 播放视频并获取指定时间的帧画面
最近做的项目要求既能播放视频(类似于视频播放器),又能每隔1s左右获取一帧视频画面,然后对图片进行处理,调查了一周,也被折磨了一周,总算找到了大致符合要求的方法.首先对调查过程中涉及到的方法进行简单介 ...
- H5调用Android播放视频
webView.loadUrl("http://10.0.2.2:8080/assets/RealNetJSCallJavaActivity.htm"); js调用的Java文件中 ...
- Unity3D Android播放视频
http://blog.csdn.net/awnuxcvbn/article/details/17719789 using UnityEngine; using System.Collections; ...
- android 播放视频时切换全屏隐藏状态栏
1. Demo: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstance ...
- android采用videoView播放视频(包装)
//android播放视频.用法:于androidManifest.xml添加activity, // <activity android:name=".PlayVideo" ...
- Cocos2dx3.11.1Android播放视频,后台 黑屏,无法记忆播放bug修改
/* * Copyright (C) 2006 The Android Open Source Project * Copyright (c) 2014 Chukong Technologies In ...
- Atitit.android播放smb 网络邻居视频文件解决方案
Atitit.android播放smb 网络邻居视频文件解决方案 Android4.4 1.1. Android4视频播放器不能直接地支持smb协议..子好先转换成个http流 1.2. ES文件浏览 ...
随机推荐
- JavaScript DOM 编程艺术(第2版)读书笔记(1)
JavaScript 简史 JavaScript 是Netscape公司与Sun公司合作开发的.在 JavaScript 1.0发布时,Netscape Navigator主宰着浏览器市场.微软在推出 ...
- C#之参数线程
public Form1() { InitializeComponent(); } Thread t; private void button1_Click(object sender, EventA ...
- 转载-python学习笔记之常用模块用法分析
内置模块(不用import就可以直接使用) 常用内置函数 help(obj) 在线帮助, obj可是任何类型 callable(obj) 查看一个obj是不是可以像函数一样调用 repr(ob ...
- Java中通过Selenium WebDriver定位iframe中的元素
转载请注明出自天外归云的博客园:http://www.cnblogs.com/LanTianYou/ 问题:有一些元素,无论是通过id或是xpath等等,怎么都定位不到. 分析:这很可能是因为你要定位 ...
- MySQL中删除重复数据的简单方法,mysql删除重复数据
MYSQL里有五百万数据,但大多是重复的,真实的就180万,于是想怎样把这些重复的数据搞出来,在网上找了一圈,好多是用NOT IN这样的代码,这样效率很低,自己琢磨组合了一下,找到一个高效的处理方式, ...
- WebForm上传文件FileUpload
//Button1的点击事件 //FileUpload1.FileName为所传文件的名字. //以DateTime.Now.ToString("yyyyMMddhhmmssms" ...
- Xcode的Architectures和Valid Architectures的区别,
登录 | 注册 ys410900345的专栏 目录视图摘要视图订阅 学院APP首次下载,可得50C币! 欢迎来帮助开源“进步” 当讲师?爱学习?投票攒课吧 CSDN 2015博 ...
- 监控windows服务,当服务停止后自动重启服务
近期花时间研究了一下windows和linux下某服务停了后自动重启的功能,在网上收集了些资料,并经过测试,在此整理一下.这里介绍的是windows服务的监控,是通过批处理来实现的.本例是监控wind ...
- Struts2的标签库(三)——控制标签
Struts2的标签库(三) --控制标签 1.if/elseif/else标签 用于分支控制,取代JSP中的if语句,根据一个boolean(test属性的值)值判断是否进行下一步运算或者输出等. ...
- SqlSever基础 left函数 从左边开始截取字符串
镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...