使用VideoView实现简单视频播放器
转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/39471397
VideoView内部封装好了Mediaplayer.Android框架提供了VideoView类来封装MediaPalyer,这个VideoView类非常好用。Android自带的程序Gallery也是用VideoView实现的。相比之下,我们使用更方便 ,实现MediaPlayer.OnCompletionListener接口,将会在Video播完的时候得到通知,本例只是简单的结束程序如下:
另附我的一个还未成熟的播放器,下载地址:http://www.eoemarket.com/soft/370334.html,正在完善中
import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.media.AudioManager; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.text.TextUtils; import android.view.Display; import android.view.GestureDetector.SimpleOnGestureListener; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.widget.ImageView; public class VideoPlayerActivity extends Activity implements OnCompletionListener { private String mPath; private String mTitle; private VideoView mVideoView; private View mVolumeBrightnessLayout; private ImageView mOperationBg; private ImageView mOperationPercent; private AudioManager mAudioManager; /** 最大声音 */ private int mMaxVolume; /** 当前声音 */ private int mVolume = -1; /** 当前亮度 */ private float mBrightness = -1f; /** 当前缩放模式 */ private int mLayout = VideoView.VIDEO_LAYOUT_ZOOM; private GestureDetector mGestureDetector; private MediaController mMediaController; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); Intent intent = getIntent(); mPath = intent.getStringExtra("path"); mTitle = intent.getStringExtra("title"); if (TextUtils.isEmpty(mPath)) mPath = Environment.getExternalStorageDirectory() + "/video/你太猖狂.flv"; else if (intent.getData() != null) mPath = intent.getData().toString(); setContentView(R.layout.videoview); mVideoView = (VideoView) findViewById(R.id.surface_view); mVolumeBrightnessLayout = findViewById(R.id.operation_volume_brightness); mOperationBg = (ImageView) findViewById(R.id.operation_bg); mOperationPercent = (ImageView) findViewById(R.id.operation_percent); mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); if (mPath.startsWith("http:")) mVideoView.setVideoURI(Uri.parse(mPath)); else mVideoView.setVideoPath(mPath); // mVideoView.setOnCompletionListener(this); mMediaController = new MediaController(this); //设置显示名称 mMediaController.setFileName(mTitle); mVideoView.setMediaController(mMediaController); mVideoView.requestFocus(); mGestureDetector = new GestureDetector(this, new MyGestureListener()); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } @Override protected void onPause() { super.onPause(); if (mVideoView != null) mVideoView.pause(); } @Override protected void onResume() { super.onResume(); if (mVideoView != null) mVideoView.resume(); } @Override protected void onDestroy() { super.onDestroy(); if (mVideoView != null) mVideoView.stopPlayback(); } @Override public boolean onTouchEvent(MotionEvent event) { if (mGestureDetector.onTouchEvent(event)) return true; // 处理手势结束 switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_UP: endGesture(); break; } return super.onTouchEvent(event); } /** 手势结束 */ private void endGesture() { mVolume = -1; mBrightness = -1f; // 隐藏 mDismissHandler.removeMessages(0); mDismissHandler.sendEmptyMessageDelayed(0, 500); } private class MyGestureListener extends SimpleOnGestureListener { /** 双击 */ @Override public boolean onDoubleTap(MotionEvent e) { if (mLayout == VideoView.VIDEO_LAYOUT_ZOOM) mLayout = VideoView.VIDEO_LAYOUT_ORIGIN; else mLayout++; if (mVideoView != null) mVideoView.setVideoLayout(mLayout, 0); return true; } /** 滑动 */ @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { float mOldX = e1.getX(), mOldY = e1.getY(); int y = (int) e2.getRawY(); Display disp = getWindowManager().getDefaultDisplay(); int windowWidth = disp.getWidth(); int windowHeight = disp.getHeight(); if (mOldX > windowWidth * 4.0 / 5)// 右边滑动 onVolumeSlide((mOldY - y) / windowHeight); else if (mOldX < windowWidth / 5.0)// 左边滑动 onBrightnessSlide((mOldY - y) / windowHeight); return super.onScroll(e1, e2, distanceX, distanceY); } } /** 定时隐藏 */ private Handler mDismissHandler = new Handler() { @Override public void handleMessage(Message msg) { mVolumeBrightnessLayout.setVisibility(View.GONE); } }; /** * 滑动改变声音大小 * * @param percent */ private void onVolumeSlide(float percent) { if (mVolume == -1) { mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); if (mVolume < 0) mVolume = 0; // 显示 mOperationBg.setImageResource(R.drawable.video_volumn_bg); mVolumeBrightnessLayout.setVisibility(View.VISIBLE); } int index = (int) (percent * mMaxVolume) + mVolume; if (index > mMaxVolume) index = mMaxVolume; else if (index < 0) index = 0; // 变更声音 mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0); // 变更进度条 ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams(); lp.width = findViewById(R.id.operation_full).getLayoutParams().width * index / mMaxVolume; mOperationPercent.setLayoutParams(lp); } /** * 滑动改变亮度 * * @param percent */ private void onBrightnessSlide(float percent) { if (mBrightness < 0) { mBrightness = getWindow().getAttributes().screenBrightness; if (mBrightness <= 0.00f) mBrightness = 0.50f; if (mBrightness < 0.01f) mBrightness = 0.01f; // 显示 mOperationBg.setImageResource(R.drawable.video_brightness_bg); mVolumeBrightnessLayout.setVisibility(View.VISIBLE); } WindowManager.LayoutParams lpa = getWindow().getAttributes(); lpa.screenBrightness = mBrightness + percent; if (lpa.screenBrightness > 1.0f) lpa.screenBrightness = 1.0f; else if (lpa.screenBrightness < 0.01f) lpa.screenBrightness = 0.01f; getWindow().setAttributes(lpa); ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams(); lp.width = (int) (findViewById(R.id.operation_full).getLayoutParams().width * lpa.screenBrightness); mOperationPercent.setLayoutParams(lp); } @Override public void onConfigurationChanged(Configuration newConfig) { if (mVideoView != null) mVideoView.setVideoLayout(mLayout, 0); super.onConfigurationChanged(newConfig); } @Override public void onCompletion(MediaPlayer player) { finish(); } }
videoView 是android 系统提供的一个媒体播放显示和控制的控件。其结构层次如下:
原型:VideoView extends SurfaceView implements MediaController.MediaPlayerControl
类结构:
java.lang.Object
↳ android.view.View
↳ android.view.SurfaceView
↳ android.widget.VideoView
通过VideoView 的原型可知:如果构建更为复杂和有特色个性的视频View,需要继承SurfaceView 和实现MediaPlayerControl接口。其中SurfaceView 为显示提供支持,MediaPlayerControl则为媒体控制提供了支持。
核心播放类:
import android.app.Activity; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; public class PlayerActivity extends Activity implements OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback { private static final String TAG = "MediaPlayerDemo"; private int mVideoWidth; private int mVideoHeight; private MediaPlayer mMediaPlayer; private SurfaceView mPreview; private SurfaceHolder holder; private String path = Environment.getExternalStorageDirectory() + "/Moon.mp4"; private boolean mIsVideoSizeKnown = false; private boolean mIsVideoReadyToBePlayed = false; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.mediaplayer); mPreview = (SurfaceView) findViewById(R.id.surface); holder = mPreview.getHolder(); holder.addCallback(this); } private void playVideo() { doCleanUp(); try { mMediaPlayer = new MediaPlayer(this); mMediaPlayer.setDataSource(path); mMediaPlayer.setDisplay(holder); mMediaPlayer.prepareAsync(); mMediaPlayer.setScreenOnWhilePlaying(true); mMediaPlayer.setOnBufferingUpdateListener(this); mMediaPlayer.setOnCompletionListener(this); mMediaPlayer.setOnPreparedListener(this); mMediaPlayer.setOnVideoSizeChangedListener(this); } catch (Exception e) { Log.e(TAG, "error: " + e.getMessage(), e); } } @Override public void onBufferingUpdate(MediaPlayer arg0, int percent) { Log.d(TAG, "onBufferingUpdate percent:" + percent); } @Override public void onCompletion(MediaPlayer arg0) { Log.d(TAG, "onCompletion called"); mMediaPlayer.release(); } @Override public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { Log.v(TAG, "onVideoSizeChanged called"); if (width == 0 || height == 0) { Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")"); return; } mIsVideoSizeKnown = true; mVideoWidth = width; mVideoHeight = height; if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) { startVideoPlayback(); } } @Override public void onPrepared(MediaPlayer mediaplayer) { Log.d(TAG, "onPrepared called"); mIsVideoReadyToBePlayed = true; if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) { startVideoPlayback(); } } @Override public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) { Log.d(TAG, "surfaceChanged called" + i + " " + j + " " + k); } @Override public void surfaceDestroyed(SurfaceHolder surfaceholder) { Log.d(TAG, "surfaceDestroyed called"); } @Override public void surfaceCreated(SurfaceHolder holder) { Log.d(TAG, "surfaceCreated called"); playVideo(); } @Override protected void onPause() { super.onPause(); releaseMediaPlayer(); doCleanUp(); } @Override protected void onDestroy() { super.onDestroy(); releaseMediaPlayer(); doCleanUp(); } private void releaseMediaPlayer() { if (mMediaPlayer != null) { mMediaPlayer.release(); mMediaPlayer = null; } } private void doCleanUp() { mVideoWidth = 0; mVideoHeight = 0; mIsVideoReadyToBePlayed = false; mIsVideoSizeKnown = false; } private void startVideoPlayback() { Log.v(TAG, "startVideoPlayback"); holder.setFixedSize(mVideoWidth, mVideoHeight); mMediaPlayer.start(); } }
第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码,即可关注。
使用VideoView实现简单视频播放器的更多相关文章
- Opencv 简单视频播放器
// C++ header and namespace #include <iostream> #include <string> #include <cstdlib&g ...
- QT-简易视频播放器
一直没找到理由去学一下QT,由于工作原因之后的工作内容会用到QT,于是这两天摸索了下:早上临时决定先做个视频播放器玩一下,于是先用qml发现不会用,无果,于是放弃了使用qml,等之后系统的看一下Jav ...
- Android 视频播放器 (一):使用VideoView播放视频
一.简介 作为Android开发,我们不可避免的会接触到视频播放,VideoView做为最简单的播放器,我们是不应该不会的. 下面简单介绍一下VideoView: VideoView是使用MediaP ...
- 安卓视频播放器(VideoView)
VideoView是安卓自带的视频播放器类,该类集成有显示和控制两大部分,在布局文件中添加VideoView然后在java文件中简单的调用控制命令,即可实现本地或者网络视频的播放.本章实现视频的居中播 ...
- 转:最简单的基于 DirectShow 的视频播放器
50行代码实现的一个最简单的基于 DirectShow 的视频播放器 本文介绍一个最简单的基于 DirectShow 的视频播放器.该播放器对于初学者来说是十分有用的,它包含了使用 DirectSho ...
- 【转】100行代码实现最简单的基于FFMPEG+SDL的视频播放器
FFMPEG工程浩大,可以参考的书籍又不是很多,因此很多刚学习FFMPEG的人常常感觉到无从下手.我刚接触FFMPEG的时候也感觉不知从何学起. 因此我把自己做项目过程中实现的一个非常简单的视频播放器 ...
- 最简单的基于FFMPEG+SDL的视频播放器 ver2 (採用SDL2.0)
===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...
- 最简单的基于DirectShow的示例:视频播放器自定义版
===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...
- 最简单的基于DirectShow的示例:视频播放器图形界面版
===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...
随机推荐
- class-map与policy-map 配置与qos模版
将subnet-a 与subnet-b 归入类class1 中.Router1(config)# ip access-list extended subnet-a Router1(config-std ...
- Nginx+Tomca+Redis实现负载均衡、资源分离、session共享
目标实现:Nginx作为负载均衡后端多Tomcat实例,通过Redis实现Session共享. 操作系统环境:CentOS 6.8 SSH:SecureCRT 其中 Nginx服务:80端口 Tomc ...
- node之fs模块
前言 fs是filesystem的缩写,该模块提供本地文件的读写能力,基本上是POSIX文件操作命令的简单包装.但是,这个模块几乎对所有操作提供异步和同步两种操作方式,供开发者选择. 一.文件读取 文 ...
- SpringBoot学习之启动探究
SpringApplication是SpringBoot的启动程序,我们通过它的run方法可以快速启动一个SpringBoot应用.可是这里面到底发生了什么?它是处于什么样的机制简化我们程序启动的?接 ...
- 64. Minimum Path Sum(中等, 又做出一个DP题, 你们非问我开不开心,当然开心喽!^^)
Given an m x n grid filled with nonnegative numbers, find a path from top left to bottom right which ...
- sololearn的c++学习记录_4m11d
Function Templates Functions and classes help to make programs easier to write, safer, and more main ...
- 使用redis做缓存
redis常本用来作为缓存服务器.缓存的好处是减少服务器的压力,数据查询速度快.解决数据响应慢的问题. 添加缓存:只用redis的Hash数据类型添加缓存. 例如:需要在查询的业务功能中,添加缓存 1 ...
- Java IO流笔记
File 类 ps:注意file的delete失败可能是输入输出流还在用这个file Java实现简单文件管理 package fileDemo; import java.io.File; impor ...
- 20160223.CCPP体系详解(0033天)
程序片段(01):MyArray.h+MyArray.c+main.c 内容概要:数组库 ///MyArray.h #pragma once #define DT int//类型通用 typedef ...
- 20160222.CCPP体系详解(0032天)
程序片段(01):宽字符.c+字符串与内存四区.c 内容概要:宽窄字符 ///宽字符.c #include <stdio.h> #include <stdlib.h> #inc ...