关于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

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的