关于android的VideoView的使用

2024-03-18 09:48
文章标签 android 使用 videoview

本文主要是介绍关于android的VideoView的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Android自带了一个VideoView,用来播放视频和网络视频,它是继承SurfaceView使用MediaPlayer来做播放的类。

VideoView使用的一个简单实例:

Layout文件:

<?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"android:background="@drawable/bg"><Buttonandroid:id="@+id/btn"android:text="@string/playbtn"android:layout_width="fill_parent"android:layout_height="wrap_content"/><VideoView android:id="@+id/videowiew"android:layout_gravity="center_horizontal"android:layout_width="fill_parent"android:layout_height="fill_parent"/></LinearLayout>

播放代码:

public class ListviewActivity extends Activity {VideoView mVideoView;Button btn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_listview);btn = (Button)findViewById(R.id.btn);mVideoView = (VideoView)findViewById(R.id.videowiew);btn.setOnClickListener(click);MediaController mController = new MediaController(this);mVideoView.setMediaController(mController);//设置一个控制条}OnClickListener click = new OnClickListener() {@Overridepublic void onClick(View v) {Uri uri = Uri.parse("http://10.0.245.2:9090/router?id=000000000000000000000566");//Uri uri = Uri.parse("http://daily3gp.com/vids/family_guy_penis_car.3gp");mVideoView.setVideoURI(uri);mVideoView.requestFocus();mVideoView.start();}};

注意要播放网络视频的话,还要在AndroidManifest.xml中加入:

<uses-permission android:name="android.permission.INTERNET" />

权限

 

显示的图像:



由于是播放的视频,所以截不到图像,中间是一个控制条,通过

MediaController mController = new MediaController(this);mVideoView.setMediaController(mController);

来加入,如果没有也可以播放,只是没有了这个控制条。这是android自带的控制条,具有暂停,快进,快退,一个进度显示条等。

完整工程代码可以到我的资源下载区下载。

http://download.csdn.net/detail/taoxugang2012/6500453


当然很多时候我们是不满足于使用别人的代码的,使用androidVideoView任然存在有些不足,比如说系统带的控制条太难看,全屏播放时无法全屏。

 

通过查看源码可以修改该VideoView类,最开始,将源代码拷贝过来用,会出现一些问题,修改了一些部分后就可用了,具体如下:

import java.io.IOException;
import java.util.Map;import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
//import android.content.res.Resources;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.net.Uri;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.MediaController;
import android.widget.MediaController.MediaPlayerControl;public class VideoView extends SurfaceView implements MediaPlayerControl {private String TAG = "VideoView";private Uri         mUri;private Map<String, String> mHeaders;private int         mDuration;private static final int STATE_ERROR              = -1;private static final int STATE_IDLE               = 0;private static final int STATE_PREPARING          = 1;private static final int STATE_PREPARED           = 2;private static final int STATE_PLAYING            = 3;private static final int STATE_PAUSED             = 4;private static final int STATE_PLAYBACK_COMPLETED = 5;private int mCurrentState = STATE_IDLE;private int mTargetState  = STATE_IDLE;private SurfaceHolder mSurfaceHolder = null;private MediaPlayer mMediaPlayer = null;private int         mVideoWidth;private int         mVideoHeight;private int         mSurfaceWidth;private int         mSurfaceHeight;private MediaController mMediaController;private OnCompletionListener mOnCompletionListener;private MediaPlayer.OnPreparedListener mOnPreparedListener;private int         mCurrentBufferPercentage;private OnErrorListener mOnErrorListener;private OnInfoListener  mOnInfoListener;private int         mSeekWhenPrepared;  private boolean     mCanPause;private boolean     mCanSeekBack;private boolean     mCanSeekForward;Context mContext;public VideoView(Context context) {super(context);mContext = context;initVideoView();}public VideoView(Context context, AttributeSet attrs) {this(context, attrs, 0);mContext = context;initVideoView();}public VideoView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);mContext = context;initVideoView();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int width = getDefaultSize(mVideoWidth, widthMeasureSpec);int height = getDefaultSize(mVideoHeight, heightMeasureSpec);if (mVideoWidth > 0 && mVideoHeight > 0) {if ( mVideoWidth * height  > width * mVideoHeight ) {height = width * mVideoHeight / mVideoWidth;} else if ( mVideoWidth * height  < width * mVideoHeight ) {width = height * mVideoWidth / mVideoHeight;} }setMeasuredDimension(width, height);}@Overridepublic void onInitializeAccessibilityEvent(AccessibilityEvent event) {super.onInitializeAccessibilityEvent(event);event.setClassName(VideoView.class.getName());}@Overridepublic void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {super.onInitializeAccessibilityNodeInfo(info);info.setClassName(VideoView.class.getName());}public int resolveAdjustedSize(int desiredSize, int measureSpec) {int result = desiredSize;int specMode = MeasureSpec.getMode(measureSpec);int specSize =  MeasureSpec.getSize(measureSpec);switch (specMode) {case MeasureSpec.UNSPECIFIED:result = desiredSize;break;case MeasureSpec.AT_MOST:result = Math.min(desiredSize, specSize);break;case MeasureSpec.EXACTLY:result = specSize;break;}return result;
}private void initVideoView() {mVideoWidth = 0;mVideoHeight = 0;getHolder().addCallback(mSHCallback);getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);setFocusable(true);setFocusableInTouchMode(true);requestFocus();mCurrentState = STATE_IDLE;mTargetState  = STATE_IDLE;}public void setVideoPath(String path) {setVideoURI(Uri.parse(path));}public void setVideoURI(Uri uri) {setVideoURI(uri, null);}/*** @hide*/public void setVideoURI(Uri uri, Map<String, String> headers) {mUri = uri;mHeaders = headers;mSeekWhenPrepared = 0;openVideo();requestLayout();invalidate();}public void stopPlayback() {if (mMediaPlayer != null) {mMediaPlayer.stop();mMediaPlayer.release();mMediaPlayer = null;mCurrentState = STATE_IDLE;mTargetState  = STATE_IDLE;}}private void openVideo() {if (mUri == null || mSurfaceHolder == null) {return;}Intent i = new Intent("com.android.music.musicservicecommand");i.putExtra("command", "pause");mContext.sendBroadcast(i);release(false);try {mMediaPlayer = new MediaPlayer();mMediaPlayer.setOnPreparedListener(mPreparedListener);mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);mDuration = -1;mMediaPlayer.setOnCompletionListener(mCompletionListener);mMediaPlayer.setOnErrorListener(mErrorListener);mMediaPlayer.setOnInfoListener(mOnInfoListener);mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);mCurrentBufferPercentage = 0;mMediaPlayer.setDataSource(mContext, mUri, mHeaders);mMediaPlayer.setDisplay(mSurfaceHolder);mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mMediaPlayer.setScreenOnWhilePlaying(true);mMediaPlayer.prepareAsync();mCurrentState = STATE_PREPARING;attachMediaController();} catch (IOException ex) {Log.w(TAG, "Unable to open content: " + mUri, ex);mCurrentState = STATE_ERROR;mTargetState = STATE_ERROR;mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);return;} catch (IllegalArgumentException ex) {Log.w(TAG, "Unable to open content: " + mUri, ex);mCurrentState = STATE_ERROR;mTargetState = STATE_ERROR;mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);return;}}public void setMediaController(MediaController controller) {if (mMediaController != null) {mMediaController.hide();}mMediaController = controller;attachMediaController();}private void attachMediaController() {if (mMediaPlayer != null && mMediaController != null) {mMediaController.setMediaPlayer(this);View anchorView = this.getParent() instanceof View ?(View)this.getParent() : this;mMediaController.setAnchorView(anchorView);mMediaController.setEnabled(isInPlaybackState());}}MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener =new MediaPlayer.OnVideoSizeChangedListener() {public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {mVideoWidth = mp.getVideoWidth();mVideoHeight = mp.getVideoHeight();if (mVideoWidth != 0 && mVideoHeight != 0) {getHolder().setFixedSize(mVideoWidth, mVideoHeight);requestLayout();}}};MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {public void onPrepared(MediaPlayer mp) {mCurrentState = STATE_PREPARED;mCanPause = true;if (mOnPreparedListener != null) {mOnPreparedListener.onPrepared(mMediaPlayer);}if (mMediaController != null) {mMediaController.setEnabled(true);}mVideoWidth = mp.getVideoWidth();mVideoHeight = mp.getVideoHeight();int seekToPosition = mSeekWhenPrepared;  if (seekToPosition != 0) {seekTo(seekToPosition);}if (mVideoWidth != 0 && mVideoHeight != 0) {getHolder().setFixedSize(mVideoWidth, mVideoHeight);if (mSurfaceWidth == mVideoWidth && mSurfaceHeight == mVideoHeight) {if (mTargetState == STATE_PLAYING) {start();if (mMediaController != null) {mMediaController.show();}} else if (!isPlaying() &&(seekToPosition != 0 || getCurrentPosition() > 0)) {if (mMediaController != null) {mMediaController.show(0);}}}} else {if (mTargetState == STATE_PLAYING) {start();}}}};private MediaPlayer.OnCompletionListener mCompletionListener =new MediaPlayer.OnCompletionListener() {public void onCompletion(MediaPlayer mp) {mCurrentState = STATE_PLAYBACK_COMPLETED;mTargetState = STATE_PLAYBACK_COMPLETED;if (mMediaController != null) {mMediaController.hide();}if (mOnCompletionListener != null) {mOnCompletionListener.onCompletion(mMediaPlayer);}}};private MediaPlayer.OnErrorListener mErrorListener =new MediaPlayer.OnErrorListener() {public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {Log.d(TAG, "Error: " + framework_err + "," + impl_err);mCurrentState = STATE_ERROR;mTargetState = STATE_ERROR;if (mMediaController != null) {mMediaController.hide();}if (mOnErrorListener != null) {if (mOnErrorListener.onError(mMediaPlayer, framework_err, impl_err)) {return true;}}if (getWindowToken() != null) {//Resources r = mContext.getResources();int messageId;if (framework_err == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {messageId = R.string.VideoView_error_text_invalid_progressive_playback;} else {messageId = R.string.VideoView_error_text_unknown;}new AlertDialog.Builder(mContext).setMessage(messageId).setPositiveButton(R.string.VideoView_error_button,new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int whichButton) {if (mOnCompletionListener != null) {mOnCompletionListener.onCompletion(mMediaPlayer);}}}).setCancelable(false).show();}return true;}};private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener =new MediaPlayer.OnBufferingUpdateListener() {public void onBufferingUpdate(MediaPlayer mp, int percent) {mCurrentBufferPercentage = percent;}};/*** Register a callback to be invoked when the media file* is loaded and ready to go.** @param l The callback that will be run*/public void setOnPreparedListener(MediaPlayer.OnPreparedListener l){mOnPreparedListener = l;}/*** Register a callback to be invoked when the end of a media file* has been reached during playback.** @param l The callback that will be run*/public void setOnCompletionListener(OnCompletionListener l){mOnCompletionListener = l;}/*** Register a callback to be invoked when an error occurs* during playback or setup.  If no listener is specified,* or if the listener returned false, VideoView will inform* the user of any errors.** @param l The callback that will be run*/public void setOnErrorListener(OnErrorListener l){mOnErrorListener = l;}/*** Register a callback to be invoked when an informational event* occurs during playback or setup.** @param l The callback that will be run*/public void setOnInfoListener(OnInfoListener l) {mOnInfoListener = l;}SurfaceHolder.Callback mSHCallback = new SurfaceHolder.Callback(){public void surfaceChanged(SurfaceHolder holder, int format,int w, int h){mSurfaceWidth = w;mSurfaceHeight = h;boolean isValidState =  (mTargetState == STATE_PLAYING);boolean hasValidSize = (mVideoWidth == w && mVideoHeight == h);if (mMediaPlayer != null && isValidState && hasValidSize) {if (mSeekWhenPrepared != 0) {seekTo(mSeekWhenPrepared);}start();}}public void surfaceCreated(SurfaceHolder holder){mSurfaceHolder = holder;openVideo();}public void surfaceDestroyed(SurfaceHolder holder){mSurfaceHolder = null;if (mMediaController != null) mMediaController.hide();release(true);}};private void release(boolean cleartargetstate) {if (mMediaPlayer != null) {mMediaPlayer.reset();mMediaPlayer.release();mMediaPlayer = null;mCurrentState = STATE_IDLE;if (cleartargetstate) {mTargetState  = STATE_IDLE;}}}@Overridepublic boolean onTouchEvent(MotionEvent ev) {if (isInPlaybackState() && mMediaController != null) {toggleMediaControlsVisiblity();}return false;}@Overridepublic boolean onTrackballEvent(MotionEvent ev) {if (isInPlaybackState() && mMediaController != null) {toggleMediaControlsVisiblity();}return false;}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event){boolean isKeyCodeSupported = keyCode != KeyEvent.KEYCODE_BACK &&keyCode != KeyEvent.KEYCODE_VOLUME_UP &&keyCode != KeyEvent.KEYCODE_VOLUME_DOWN &&keyCode != KeyEvent.KEYCODE_VOLUME_MUTE &&keyCode != KeyEvent.KEYCODE_MENU &&keyCode != KeyEvent.KEYCODE_CALL &&keyCode != KeyEvent.KEYCODE_ENDCALL;if (isInPlaybackState() && isKeyCodeSupported && mMediaController != null) {if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK ||keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) {if (mMediaPlayer.isPlaying()) {pause();mMediaController.show();} else {start();mMediaController.hide();}return true;} else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY) {if (!mMediaPlayer.isPlaying()) {start();mMediaController.hide();}return true;} else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP|| keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) {if (mMediaPlayer.isPlaying()) {pause();mMediaController.show();}return true;} else {toggleMediaControlsVisiblity();}}return super.onKeyDown(keyCode, event);}private void toggleMediaControlsVisiblity() {if (mMediaController.isShowing()) {mMediaController.hide();} else {mMediaController.show();}}public void start() {if (isInPlaybackState()) {mMediaPlayer.start();mCurrentState = STATE_PLAYING;}mTargetState = STATE_PLAYING;}public void pause() {if (isInPlaybackState()) {if (mMediaPlayer.isPlaying()) {mMediaPlayer.pause();mCurrentState = STATE_PAUSED;}}mTargetState = STATE_PAUSED;}public void suspend() {release(false);}public void resume() {openVideo();}public int getDuration() {if (isInPlaybackState()) {if (mDuration > 0) {return mDuration;}mDuration = mMediaPlayer.getDuration();return mDuration;}mDuration = -1;return mDuration;}public int getCurrentPosition() {if (isInPlaybackState()) {return mMediaPlayer.getCurrentPosition();}return 0;}public void seekTo(int msec) {if (isInPlaybackState()) {mMediaPlayer.seekTo(msec);mSeekWhenPrepared = 0;} else {mSeekWhenPrepared = msec;}}public boolean isPlaying() {return isInPlaybackState() && mMediaPlayer.isPlaying();}public int getBufferPercentage() {if (mMediaPlayer != null) {return mCurrentBufferPercentage;}return 0;}private boolean isInPlaybackState() {return (mMediaPlayer != null &&mCurrentState != STATE_ERROR &&mCurrentState != STATE_IDLE &&mCurrentState != STATE_PREPARING);}public boolean canPause() {return mCanPause;}public boolean canSeekBackward() {return mCanSeekBack;}public boolean canSeekForward() {return mCanSeekForward;}
}
这个代码没有做功能性修改,只是做了简单移植,编译通过,能够正常播放。

要使用自己定义的videoview,还需要在自己的xml写上完整控件路径

<com.example.listview.VideoView 

    android:id="@+id/videowiew"

    android:layout_gravity="center_horizontal"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"/>


这个部分,还不算完美,我之后还想把android的控制条重写。






这篇关于关于android的VideoView的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/821956

相关文章

C#中checked关键字的使用小结

《C#中checked关键字的使用小结》本文主要介绍了C#中checked关键字的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录✅ 为什么需要checked? 问题:整数溢出是“静默China编程”的(默认)checked的三种用

C#中预处理器指令的使用小结

《C#中预处理器指令的使用小结》本文主要介绍了C#中预处理器指令的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录 第 1 名:#if/#else/#elif/#endif✅用途:条件编译(绝对最常用!) 典型场景: 示例

Mysql中RelayLog中继日志的使用

《Mysql中RelayLog中继日志的使用》MySQLRelayLog中继日志是主从复制架构中的核心组件,负责将从主库获取的Binlog事件暂存并应用到从库,本文就来详细的介绍一下RelayLog中... 目录一、什么是 Relay Log(中继日志)二、Relay Log 的工作流程三、Relay Lo

使用Redis实现会话管理的示例代码

《使用Redis实现会话管理的示例代码》文章介绍了如何使用Redis实现会话管理,包括会话的创建、读取、更新和删除操作,通过设置会话超时时间并重置,可以确保会话在用户持续活动期间不会过期,此外,展示了... 目录1. 会话管理的基本概念2. 使用Redis实现会话管理2.1 引入依赖2.2 会话管理基本操作

Springboot请求和响应相关注解及使用场景分析

《Springboot请求和响应相关注解及使用场景分析》本文介绍了SpringBoot中用于处理HTTP请求和构建HTTP响应的常用注解,包括@RequestMapping、@RequestParam... 目录1. 请求处理注解@RequestMapping@GetMapping, @PostMappin

springboot3.x使用@NacosValue无法获取配置信息的解决过程

《springboot3.x使用@NacosValue无法获取配置信息的解决过程》在SpringBoot3.x中升级Nacos依赖后,使用@NacosValue无法动态获取配置,通过引入SpringC... 目录一、python问题描述二、解决方案总结一、问题描述springboot从2android.x

SpringBoot整合AOP及使用案例实战

《SpringBoot整合AOP及使用案例实战》本文详细介绍了SpringAOP中的切入点表达式,重点讲解了execution表达式的语法和用法,通过案例实战,展示了AOP的基本使用、结合自定义注解以... 目录一、 引入依赖二、切入点表达式详解三、案例实战1. AOP基本使用2. AOP结合自定义注解3.

Python中Request的安装以及简单的使用方法图文教程

《Python中Request的安装以及简单的使用方法图文教程》python里的request库经常被用于进行网络爬虫,想要学习网络爬虫的同学必须得安装request这个第三方库,:本文主要介绍P... 目录1.Requests 安装cmd 窗口安装为pycharm安装在pycharm设置中为项目安装req

使用Python将PDF表格自动提取并写入Word文档表格

《使用Python将PDF表格自动提取并写入Word文档表格》在实际办公与数据处理场景中,PDF文件里的表格往往无法直接复制到Word中,本文将介绍如何使用Python从PDF文件中提取表格数据,并将... 目录引言1. 加载 PDF 文件并准备 Word 文档2. 提取 PDF 表格并创建 Word 表格

使用Python实现局域网远程监控电脑屏幕的方法

《使用Python实现局域网远程监控电脑屏幕的方法》文章介绍了两种使用Python在局域网内实现远程监控电脑屏幕的方法,方法一使用mss和socket,方法二使用PyAutoGUI和Flask,每种方... 目录方法一:使用mss和socket实现屏幕共享服务端(被监控端)客户端(监控端)方法二:使用PyA