Android笔记:视屏播放、VideoView、surfaceView,简易视频播放

简介:

一、VideoView方法

1.activity_video.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<RelativeLayout xmlns:android= "http://schemas.android.com/apk/res/android"
     xmlns:tools= "http://schemas.android.com/tools"
     android:layout_width= "match_parent"
     android:layout_height= "match_parent"
     tools:context= ".VideoActivity"  >
 
     <VideoView
         android:id= "@+id/video_videoView"
         android:layout_width= "fill_parent"
         android:layout_height= "fill_parent"
         android:layout_alignParentLeft= "true"
         android:layout_alignParentTop= "true"  />
 
</RelativeLayout>


2.代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package  com.example.vediotest;
 
import  android.media.MediaPlayer;
import  android.net.Uri;
import  android.os.Bundle;
import  android.app.Activity;
import  android.content.pm.ActivityInfo;
import  android.view.Menu;
import  android.view.Window;
import  android.view.WindowManager;
import  android.widget.MediaController;
import  android.widget.VideoView;
 
public  class  VideoActivity  extends  Activity
{
     
     private  VideoView videoView;
     private  Uri mUri;
     private  int  mPositionWhenPaused;
     
     @Override
     protected  void  onCreate(Bundle savedInstanceState)
     {
         super .onCreate(savedInstanceState);
         
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // 设置成全屏模式
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); // 强制为横屏
         setContentView(R.layout.activity_video);
         
         String url =  "http://videofile.xxxx.cn/Upload/Video/File/20140411/201404110228168972.mp4" ;
         // String url =
         // "http://player.youku.com/player.php/sid/XNDYwOTEzNzQ4/v.swf";
         
         mUri = Uri.parse(url);
         
         videoView = (VideoView) findViewById(R.id.video_videoView);
         MediaController mediaController =  new  MediaController( this );
         videoView.setMediaController(mediaController);
         
         // videoView.setVideoPath("/sdcard/xyx.3gp");
         // videoView.setVideoURI(mUri);
         // videoView.requestFocus();
         // videoView.start();
         
     }
     
     public  void  onStart()
     {
         // Play Video
         videoView.setVideoURI(mUri);
         videoView.start();
         
         super .onStart();
     }
     
     public  void  onPause()
     {
         // Stop video when the activity is pause.
         mPositionWhenPaused = videoView.getCurrentPosition();
         videoView.stopPlayback();
         
         super .onPause();
     }
     
     public  void  onResume()
     {
         // Resume video player
         if  (mPositionWhenPaused >=  0 )
         {
             videoView.seekTo(mPositionWhenPaused);
             mPositionWhenPaused = - 1 ;
         }
         
         super .onResume();
     }
     
     public  boolean  onError(MediaPlayer player,  int  arg1,  int  arg2)
     {
         return  false ;
     }
     
     public  void  onCompletion(MediaPlayer mp)
     {
         this .finish();
     }
}



二、surfaceView方法

(一)

1.activity_video_surface.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<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= "标题"  />
 
     <SurfaceView
         android:id= "@+id/surfaceVideo_surfaceView"
         android:layout_width= "wrap_content"
         android:layout_height= "wrap_content"
         android:layout_gravity= "center"  >
     </SurfaceView>
 
</LinearLayout>


2.代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package  com.example.vediotest;
 
import  android.media.AudioManager;
import  android.media.MediaPlayer;
import  android.media.MediaPlayer.OnBufferingUpdateListener;
import  android.media.MediaPlayer.OnCompletionListener;
import  android.media.MediaPlayer.OnPreparedListener;
import  android.net.Uri;
import  android.os.Bundle;
import  android.app.Activity;
import  android.util.Log;
import  android.view.Menu;
import  android.view.SurfaceHolder;
import  android.view.SurfaceHolder.Callback;
import  android.view.SurfaceView;
 
public  class  SurfaceVideoActivity  extends  Activity  implements  Callback, OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener
{
     
     private  int  width =  0 ;
     private  int  height =  0 ;
     private  MediaPlayer mMediaPlayer =  null ;
     private  SurfaceView mSurfaceView =  null ;
     private  SurfaceHolder holder =  null ;
     private  String path =  "" ;
     
     @Override
     protected  void  onCreate(Bundle savedInstanceState)
     {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_video_surface);
         
         mSurfaceView = (SurfaceView)  this .findViewById(R.id.surfaceVideo_surfaceView);
         holder = mSurfaceView.getHolder();
         holder.addCallback( this );
         holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // 设置风格
         
     }
     
     public  void  playVedio()
     {
         try
         {
             path = android.os.Environment.getExternalStorageDirectory() +  "/moto_0012.3gp" ;
             mMediaPlayer =  new  MediaPlayer();
             // mMediaPlayer.setDataSource(path);
             
           String url =  "http://videofile.housebox.cn/Upload/Video/File/20140411/201404110228168972.mp4" ;
//            String url = "http://player.youku.com/player.php/sid/XNDYwOTEzNzQ4/v.swf";
             
             mMediaPlayer.setDataSource( this , Uri.parse(url));
             mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
             mMediaPlayer.setDisplay(holder);
             mMediaPlayer.prepare(); // 准备
             Log.e( "TAG-Duration" , mMediaPlayer.getDuration() +  "" );
             mMediaPlayer.setOnBufferingUpdateListener( this );
             mMediaPlayer.setOnCompletionListener( this );
             mMediaPlayer.setOnPreparedListener( this );
         }
         catch  (Exception ex)
         {
             
         }
     }
     
     public  void  onBufferingUpdate(MediaPlayer mp,  int  percent)
     {
         // TODO Auto-generated method stub
         Log.i( "TAG-onBufferingUpdate" , percent +  "|"  + mMediaPlayer.getCurrentPosition());
     }
     
     public  void  onCompletion(MediaPlayer mp)
     {
         // TODO Auto-generated method stub
         Log.i( "TAG-onCompletion" "Completion" );
     }
     
     public  void  onPrepared(MediaPlayer mp)
     {
         // TODO Auto-generated method stub
         width = mMediaPlayer.getVideoWidth();
         height = mMediaPlayer.getVideoHeight();
         if  (width !=  0  && height !=  0 )
         {
             holder.setFixedSize(width, height); // 设置视频高宽
             mMediaPlayer.start();
             Log.i( "TAG-Duration2" , mMediaPlayer.getDuration() +  "" );
         }
     }
     
     public  void  surfaceChanged(SurfaceHolder holder,  int  format,  int  width,  int  height)
     {
         // TODO Auto-generated method stub
         
     }
     
     public  void  surfaceCreated(SurfaceHolder holder)
     {
         // TODO Auto-generated method stub
         playVedio();
     }
     
     public  void  surfaceDestroyed(SurfaceHolder holder)
     {
         // TODO Auto-generated method stub
         Log.i( "TAG-surfaceDestroyed" "surfaceDestroyed" );
     }
     
     @Override
     protected  void  onPause()
     {
         super .onPause();
         if  (mMediaPlayer !=  null )
         {
             if  (mMediaPlayer.isPlaying())
             {
                 mMediaPlayer.stop();
             }
             mMediaPlayer.reset();
             mMediaPlayer.release();
             mMediaPlayer =  null ;
         }
     }
     
}


(二)

  1. activity_video_surface2.xml

1
2
3
4
5
6
7
8
9
10
11
12
<RelativeLayout xmlns:android= "http://schemas.android.com/apk/res/android"
     android:layout_width= "fill_parent"
     android:layout_height= "fill_parent"  >
 
     <SurfaceView
         android:id= "@+id/surface2_surfaceView"
         android:layout_width= "wrap_content"
         android:layout_height= "wrap_content"
         android:layout_gravity= "center"  >
     </SurfaceView>
 
</RelativeLayout>


2.代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package  com.example.vediotest;
 
import  java.io.IOException;
 
import  android.media.AudioManager;
import  android.media.MediaPlayer;
import  android.media.MediaPlayer.OnBufferingUpdateListener;
import  android.media.MediaPlayer.OnCompletionListener;
import  android.net.Uri;
import  android.os.Bundle;
import  android.app.Activity;
import  android.content.pm.ActivityInfo;
import  android.util.Log;
import  android.view.Menu;
import  android.view.SurfaceHolder;
import  android.view.SurfaceView;
import  android.view.Window;
 
public  class  SurfaceVideo2Activity  extends  Activity  implements  OnBufferingUpdateListener, OnCompletionListener, MediaPlayer.OnPreparedListener,
         SurfaceHolder.Callback
{
     private  MediaPlayer mediaPlayer;
     private  SurfaceView surfaceView;
     private  SurfaceHolder surfaceHolder;
     private  int  videoWidth;
     private  int  videoHeight;
     
     @Override
     protected  void  onCreate(Bundle savedInstanceState)
     {
         super .onCreate(savedInstanceState);
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         setContentView(R.layout.activity_video_surface2);
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); // 强制为横屏
         this .surfaceView = (SurfaceView)  this .findViewById(R.id.surface2_surfaceView);
         this .surfaceHolder =  this .surfaceView.getHolder();
         this .surfaceHolder.addCallback( this );
         this .surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
         Log.v( "cat" ">>>create ok." );
         
     }
     
     private  void  playVideo()  throws  IllegalArgumentException, IllegalStateException, IOException
     {
       String url =  "http://videofile.housebox.cn/Upload/Video/File/20140411/201404110228168972.mp4" ;
//        String url = "http://player.youku.com/player.php/sid/XNDYwOTEzNzQ4/v.swf";
         
         
         this .mediaPlayer =  new  MediaPlayer();
//        this.mediaPlayer.setDataSource("/sdcard/daoxiang.3gp");
         this .mediaPlayer.setDataSource( this , Uri.parse(url));
         
         this .mediaPlayer.setDisplay( this .surfaceHolder);
         this .mediaPlayer.prepare();
         this .mediaPlayer.setOnBufferingUpdateListener( this );
         this .mediaPlayer.setOnPreparedListener( this );
         this .mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
         Log.i( "mplayer" ">>>play video" );
     }
     
     @Override
     public  void  surfaceChanged(SurfaceHolder arg0,  int  arg1,  int  arg2,  int  arg3)
     {
         Log.i( "cat" ">>>surface changed" );
     }
     
     @Override
     public  void  surfaceCreated(SurfaceHolder holder)
     {
         try
         {
             this .playVideo();
         }
         catch  (Exception e)
         {
             Log.i( "cat" ">>>error" , e);
         }
         Log.i( "cat" ">>>surface created" );
     }
     
     @Override
     public  void  surfaceDestroyed(SurfaceHolder holder)
     {
         Log.v( "mplayer" ">>>surface destroyed" );
     }
     
     @Override
     public  void  onCompletion(MediaPlayer arg0)
     {
         // TODO Auto-generated method stub
     }
     
     @Override
     public  void  onBufferingUpdate(MediaPlayer mp,  int  percent)
     {
         // TODO Auto-generated method stub
     }
     
     @Override
     public  void  onPrepared(MediaPlayer arg0)
     {
         this .videoWidth =  this .mediaPlayer.getVideoWidth();
         this .videoHeight =  this .mediaPlayer.getVideoHeight();
         if  ( this .videoHeight !=  0  &&  this .videoWidth !=  0 )
         {
             this .surfaceHolder.setFixedSize( this .videoWidth,  this .videoHeight);
             this .mediaPlayer.start();
         }
     }
     
     @Override
     protected  void  onDestroy()
     {
         super .onDestroy();
         if  ( this .mediaPlayer !=  null )
         {
             this .mediaPlayer.release();
             this .mediaPlayer =  null ;
         }
     }
     
}




本文转自 glblong 51CTO博客,原文链接:http://blog.51cto.com/glblong/1414232,如需转载请自行联系原作者

目录
相关文章
|
4月前
|
存储 缓存 Android开发
安卓Jetpack Compose+Kotlin, 使用ExoPlayer播放多个【远程url】音频,搭配Okhttp库进行下载和缓存,播放完随机播放下一首
这是一个Kotlin项目,使用Jetpack Compose和ExoPlayer框架开发Android应用,功能是播放远程URL音频列表。应用会检查本地缓存,如果文件存在且大小与远程文件一致则使用缓存,否则下载文件并播放。播放完成后或遇到异常,会随机播放下一首音频,并在播放前随机设置播放速度(0.9到1.2倍速)。代码包括ViewModel,负责音频管理和播放逻辑,以及UI层,包含播放和停止按钮。
|
1月前
|
安全 Android开发 Kotlin
Android经典实战之SurfaceView原理和实践
本文介绍了 `SurfaceView` 这一强大的 UI 组件,尤其适合高性能绘制任务,如视频播放和游戏。文章详细讲解了 `SurfaceView` 的原理、与 `Surface` 类的关系及其实现示例,并强调了使用时需注意的线程安全、生命周期管理和性能优化等问题。
118 8
|
15天前
|
Web App开发 安全 程序员
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
多年的互联网寒冬在今年尤为凛冽,坚守安卓开发愈发不易。面对是否转行或学习新技术的迷茫,安卓程序员可从三个方向进阶:1)钻研谷歌新技术,如Kotlin、Flutter、Jetpack等;2)拓展新功能应用,掌握Socket、OpenGL、WebRTC等专业领域技能;3)结合其他行业,如汽车、游戏、安全等,拓宽职业道路。这三个方向各有学习难度和保饭碗指数,助你在安卓开发领域持续成长。
42 1
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
|
4天前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
28 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
4月前
|
存储 数据库 Android开发
安卓Jetpack Compose+Kotlin,支持从本地添加音频文件到播放列表,支持删除,使用ExoPlayer播放音乐
为了在UI界面添加用于添加和删除本地音乐文件的按钮,以及相关的播放功能,你需要实现以下几个步骤: 1. **集成用户选择本地音乐**:允许用户从设备中选择音乐文件。 2. **创建UI按钮**:在界面中创建添加和删除按钮。 3. **数据库功能**:使用Room数据库来存储音频文件信息。 4. **更新ViewModel**:处理添加、删除和播放音频文件的逻辑。 5. **UI实现**:在UI层支持添加、删除音乐以及播放功能。
|
1月前
|
Android开发
Android中SurfaceView的双缓冲机制和普通View叠加问题解决办法
本文介绍了 Android 平台上的 SurfaceView,这是一种高效的图形渲染控件,尤其适用于视频播放、游戏和图形动画等场景。文章详细解释了其双缓冲机制,该机制通过前后缓冲区交换来减少图像闪烁,提升视觉体验。然而,SurfaceView 与普通 View 叠加时可能存在 Z-Order 不一致、同步问题及混合渲染难题。文中提供了使用 TextureView、调整 Z-Order 和创建自定义组合控件等多种解决方案。
89 9
|
2月前
|
JavaScript 前端开发 Java
FFmpeg开发笔记(四十七)寒冬下安卓程序员的几个技术转型发展方向
IT寒冬使APP开发门槛提升,安卓程序员需转型。选项包括:深化Android开发,跟进Google新技术如Kotlin、Jetpack、Flutter及Compose;研究Android底层框架,掌握AOSP;转型Java后端开发,学习Spring Boot等框架;拓展大前端技能,掌握JavaScript、Node.js、Vue.js及特定框架如微信小程序、HarmonyOS;或转向C/C++底层开发,通过音视频项目如FFmpeg积累经验。每条路径都有相应的书籍和技术栈推荐,助你顺利过渡。
55 3
FFmpeg开发笔记(四十七)寒冬下安卓程序员的几个技术转型发展方向
|
2月前
|
Android开发
Android 利用MediaPlayer实现音乐播放
本文提供了一个简单的Android MediaPlayer音乐播放示例,包括创建PlayerActivity、配置AndroidManifest.xml和activity_player.xml布局,以及实现播放和暂停功能的代码。
22 0
Android 利用MediaPlayer实现音乐播放
|
2月前
|
编解码 网络协议 开发工具
Android平台如何实现多路低延迟RTSP|RTMP播放?
本文档详细介绍了大牛直播SDK在Android平台上实现RTSP与RTMP流媒体播放及录像功能的技术细节。早在2015年,SDK的第一版就已经支持了多实例播放,并且通过简单的实例封装就能轻松实现。文档中提供了代码示例,展示了如何开启播放、停止播放以及开始和停止录像等功能。此外,SDK还提供了丰富的配置选项,例如设置录像目录、文件大小限制、转码选项等。总结部分列出了该SDK的关键特性,包括但不限于高稳定性和低延迟的播放能力、多实例支持、事件回调、硬解码支持、网络状态监控以及复杂的网络环境处理等。这些功能使得SDK能够应对各种应用场景,特别是在对延迟和稳定性有极高要求的情况下表现优异。
|
2月前
|
编解码 网络协议 vr&ar
Android平台下VR头显如何低延迟播放4K以上超高分辨率RTSP|RTMP流
这段内容讲述了VR头显中实现高分辨率视频播放的技术背景与实现方法,并强调了其重要性。高分辨率对于提升VR体验至关重要,它能提供更清晰的画面、增强沉浸感、补偿透镜放大效应,并维持宽广视场角下的图像质量。文中提到的大牛直播SDK具备极低的延迟(200-400ms),支持多种协议与格式,并具有丰富的功能特性,如多实例播放、事件回调、视频及音频格式支持等。此外,提供了基于Unity的播放器示例代码,展示了如何配置播放参数并开始播放。最后,作者指出此类技术在远程控制、虚拟仿真等应用场景中的重要意义。