Android ijkplayer的使用解析

来源:互联网 发布:示波器y轴输入端口 编辑:程序博客网 时间:2024/06/07 05:20



http://www.2cto.com/kf/201703/619114.html


http://www.2cto.com/kf/201703/619114.html


Android ijkplayer的使用解析

ijkplayer是Bilibili基于ffmpeg开发并开源的轻量级视频播放器,支持播放本地网络视频,也支持流媒体播放。支持Android&iOS。

ijkplayer的编译这里不多阐述,我也是直接获取别人编译完成的so库文件,直接使用的。如果你对ijkplayer的编译感兴趣,可以百度一下,有很多文章。

使用ijkplayer

导包

ijkplayer源码官方下载地址:https://github.com/Bilibili/ijkplayer
上面是官方提供的ijkplayer的源码地址,但是它是没有编译过的。下面我给大家分享一份编译好的ijkplayer源码,由于比较大,分了三个包才上传完成,需要三个包都下载后才能一起解压:
编译好的ijkplayer.part1
编译好的ijkplayer.part2
编译好的ijkplayer.part3

我们下载完成,进入android/ijkplayer目录:
<img alt="这里写图片描述" src="http://www.2cto.com/uploadfile/Collfiles/20170329/20170329091248241.png" title="" kf="" ware="" vc="" "="" target="_blank" class="keylink" style="border-width: 0px; padding: 0px; margin: 0px auto; list-style: none; display: block; width: 438px; height: 169px;">vczltcShozwvbGk+DQo8bGk+aWprcGxheWVyLWV4b6O6Z29vZ2xlv6rUtLXE0ru49tDCtcSypbfFxvdFeG9QbGF5ZXKjrNTaRGVtb9bQus1pamtwbGF5ZXK21LHI08O1xKGjzai5/bCy17BpamtwbGF5ZXK/ydLUt6LP1nNldHRpbmfA78Pmv8nS1NGh1PGyu82scGxheWVywLTk1si+tuDDvczlz9TKvqOsuMPEo7/pz8LD5r7NysfSu7j2TWVkaWFQbGF5ZXKhozwvbGk+DQo8bGk+aWprcGxheWVyLWV4YW1wbGWjurLiytSzzNDyPC9saT4NCjxsaT5pamtwbGF5ZXIte2FyY2h9o7qx4NLrs/bAtLXEuPe49rDmsb61xC5zb87EvP6how0KPHA+udm3vczhuam1xERlbW+1xLT6wuu7ucrHzaa24LXEo6zJ9dbBu7nTw8HLb3R0byzQ6NKqttS52be9tcRkZW1vvfjQ0L6rvPKjrMils/3Su9Cp08Oyu7W9tcS0+sLroaM8YnIgLz4NCsrXz8jQ6NKqtcTKx2lqa3BsYXllci17YXJjaH2homlqa3BsYXllci08YSBjbGFzcz0="replace_word" href="http://lib.csdn.net/base/javase" target="_blank" title="Java SE知识库">Java两个库。exo是Google提供的新的播放器,这里不需要,直接砍掉。其次是ijkplayer-example里的,我们需要的只有tv.danmaku.ijk.media.example.widget.media包下的部分类。
注:
链接库ijkplayer-arm64,ijkplayer-armv5,ijkplayer-armv7a,ijkplayer-x86,ijkplayer-x86_64是不同体系架构的动态链接库,在当前工程结构里面作为一个模块,如果不想做兼容多平台问题,可以删除其他目录结构,单独保留自己需要的平台目录。

新建一个工程:
(1)把ijkplayer-armv7a/src/main/libs下的文件拷贝到新工程app目录的libs下。
(2)把ijkplayer-java/build/outputs/aar/ijkplayer-java-release.aar复制到新工程app目录的libs下。
(3)修改APP下的build.gradle, 主要设置.so及.aar的位置:

?
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
apply plugin: 'com.android.application'
 
android {
    compileSdkVersion24
    buildToolsVersion"25.0.0"
    defaultConfig {
        applicationId"com.hx.ijkplayer_demo"
        minSdkVersion14
        targetSdkVersion24
        versionCode1
        versionName"1.0"
        testInstrumentationRunner"android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabledfalse
            proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
        }
    }
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs'/**在libs文件夹下找so文件*/
        }
    }
}
 
repositories {
    mavenCentral()
    flatDir {
        dirs'libs'/**在libs文件夹下找aar文件*/
    }
}
 
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile'com.android.support:appcompat-v7:24.2.1'
    testCompile'junit:junit:4.12'
    compile(name:'ijkplayer-java-release', ext: 'aar')/**编译ijkplayer-java-release.aar文件*/
}

(4)复制ijkplayer-example下面的tv.danmaku.ijk.media.example.widget.media到新的工程,删掉一些不需要类。
这里写图片描述

(5)IjkVideoView里面还是有很多如exo等没用的东西,删!具体可以参见我后面的Demo。

(6)Manifest

?
1
2
3
4
5
6
...
 
...
</activity>
..
<uses-permission android:name="android.permission.INTERNET"></uses-permission>

播放实现

Xml代码

?
1
2
3
4
5
<!--?xml version="1.0"encoding="utf-8"?-->
<relativelayout android:layout_height="match_parent"android:layout_width="match_parent"tools:context=".MainActivity"xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools">
 
  <com.hx.ijkplayer_demo.widget.media.ijkvideoview android:id="@+id/video_view"android:layout_height="match_parent"android:layout_width="match_parent">
</com.hx.ijkplayer_demo.widget.media.ijkvideoview></relativelayout>

Java代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
publicclass MainActivity extendsAppCompatActivity {
 
    privateIjkVideoView videoView;
 
    @Override
    protectedvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        videoView = (IjkVideoView) findViewById(R.id.video_view);
        videoView.setAspectRatio(IRenderView.AR_ASPECT_FIT_PARENT);
        videoView.setVideoURI(Uri.parse("http://zv.3gv.ifeng.com/live/zhongwen800k.m3u8"));
        videoView.start();
    }
}

常用函数

?
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
/**
 * 参数aspectRatio(缩放参数)参见IRenderView的常量:IRenderView.AR_ASPECT_FIT_PARENT,
IRenderView.AR_ASPECT_FILL_PARENT,
IRenderView.AR_ASPECT_WRAP_CONTENT,
IRenderView.AR_MATCH_PARENT,
IRenderView.AR_16_9_FIT_PARENT,
IRenderView.AR_4_3_FIT_PARENT
 */
publicvoid setAspectRatio(intaspectRatio);
//改变视频缩放状态。
publicint toggleAspectRatio();
//设置视频路径。
publicvoid setVideoPath(String path);
//设置视频URI。(可以是网络视频地址)
publicvoid setVideoURI(Uri uri);
//停止视频播放,并释放资源。
publicvoid stopPlayback();
/**
 * 设置媒体控制器。
 * 参数controller:媒体控制器,注意是com.hx.ijkplayer_demo.widget.media.IMediaController。
 */
publicvoid setMediaController(IMediaController controller);
//改变媒体控制器显隐
privatevoid toggleMediaControlsVisiblity();
//注册一个回调函数,在视频预处理完成后调用。在视频预处理完成后被调用。此时视频的宽度、高度、宽高比信息已经获取到,此时可调用seekTo让视频从指定位置开始播放。
publicvoid setOnPreparedListener(OnPreparedListener l);
//播放完成回调
publicvoid setOnCompletionListener(IMediaPlayer.OnCompletionListener l);
//播放错误回调
publicvoid setOnErrorListener(IMediaPlayer.OnErrorListener l);
//事件发生回调
publicvoid setOnInfoListener(IMediaPlayer.OnInfoListener l);
//获取总长度
publicint getDuration();
//获取当前播放位置。
publiclong getCurrentPosition();
//设置播放位置。单位毫秒
publicvoid seekTo(longmsec);
//是否正在播放。
publicboolean isPlaying();
//获取缓冲百分比。
publicint getBufferPercentage();

封装ijkplayer

上面只是ijkplayer的一个基本用法。我们可以对ijkplayer进行一次封装,让ijkplayer使用起来更加简单。

功能:

  • 使用Vitamio的VideoView进行视频播放
  • 视频左侧界面(左1/2以内)上下滑动调节亮度
  • 视频右侧界面(右1/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
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    publicclass PlayerManager {
        /**
         * 可能会剪裁,保持原视频的大小,显示在中心,当原视频的大小超过view的大小超过部分裁剪处理
         */
        publicstatic final String SCALETYPE_FITPARENT="fitParent";
        /**
         * 可能会剪裁,等比例放大视频,直到填满View为止,超过View的部分作裁剪处理
         */
        publicstatic final String SCALETYPE_FILLPARENT="fillParent";
        /**
         * 将视频的内容完整居中显示,如果视频大于view,则按比例缩视频直到完全显示在view中
         */
        publicstatic final String SCALETYPE_WRAPCONTENT="wrapContent";
        /**
         * 不剪裁,非等比例拉伸画面填满整个View
         */
        publicstatic final String SCALETYPE_FITXY="fitXY";
        /**
         * 不剪裁,非等比例拉伸画面到16:9,并完全显示在View中
         */
        publicstatic final String SCALETYPE_16_9="16:9";
        /**
         * 不剪裁,非等比例拉伸画面到4:3,并完全显示在View中
         */
        publicstatic final String SCALETYPE_4_3="4:3";
     
        /**
         * 状态常量
         */
        privatefinal int STATUS_ERROR=-1;
        privatefinal int STATUS_IDLE=0;
        privatefinal int STATUS_LOADING=1;
        privatefinal int STATUS_PLAYING=2;
        privatefinal int STATUS_PAUSE=3;
        privatefinal int STATUS_COMPLETED=4;
     
        privatefinal Activity activity;
        privatefinal IjkVideoView videoView;
        privatefinal AudioManager audioManager;
        publicGestureDetector gestureDetector;
     
        privateboolean playerSupport;
        privateboolean isLive = false;//是否为直播
        privateboolean fullScreenOnly;
        privateboolean portrait;
     
        privatefinal int mMaxVolume;
        privateint screenWidthPixels;
        privateint currentPosition;
        privateint status=STATUS_IDLE;
        privatelong pauseTime;
        privateString url;
     
        privatefloat brightness=-1;
        privateint volume=-1;
        privatelong newPosition = -1;
        privatelong defaultRetryTime=5000;
     
        privateOrientationEventListener orientationEventListener;
        privatePlayerStateListener playerStateListener;
     
        publicvoid setPlayerStateListener(PlayerStateListener playerStateListener) {
            this.playerStateListener = playerStateListener;
        }
     
        privateOnErrorListener onErrorListener=newOnErrorListener() {
            @Override
            publicvoid onError(intwhat, intextra) {
            }
        };
     
        privateOnCompleteListener onCompleteListener=newOnCompleteListener() {
            @Override
            publicvoid onComplete() {
            }
        };
     
        privateOnInfoListener onInfoListener=newOnInfoListener(){
            @Override
            publicvoid onInfo(intwhat, intextra) {
     
            }
        };
        privateOnControlPanelVisibilityChangeListener onControlPanelVisibilityChangeListener=newOnControlPanelVisibilityChangeListener() {
            @Override
            publicvoid change(booleanisShowing) {
            }
        };
     
        /**
         * try to play when error(only for live video)
         * @param defaultRetryTime millisecond,0 will stop retry,default is 5000 millisecond
         */
        publicvoid setDefaultRetryTime(longdefaultRetryTime) {
            this.defaultRetryTime = defaultRetryTime;
        }
     
        publicPlayerManager(finalActivity activity) {
            try{
                IjkMediaPlayer.loadLibrariesOnce(null);
                IjkMediaPlayer.native_profileBegin("libijkplayer.so");
                playerSupport=true;
            }catch(Throwable e) {
                Log.e("GiraffePlayer","loadLibraries error", e);
            }
            this.activity=activity;
            screenWidthPixels = activity.getResources().getDisplayMetrics().widthPixels;
     
            videoView = (IjkVideoView) activity.findViewById(R.id.video_view);
            videoView.setOnCompletionListener(newIMediaPlayer.OnCompletionListener() {
                @Override
                publicvoid onCompletion(IMediaPlayer mp) {
                    statusChange(STATUS_COMPLETED);
                    onCompleteListener.onComplete();
                }
            });
            videoView.setOnErrorListener(newIMediaPlayer.OnErrorListener() {
                @Override
                publicboolean onError(IMediaPlayer mp, intwhat, intextra) {
                    statusChange(STATUS_ERROR);
                    onErrorListener.onError(what,extra);
                    returntrue;
                }
            });
            videoView.setOnInfoListener(newIMediaPlayer.OnInfoListener() {
                @Override
                publicboolean onInfo(IMediaPlayer mp, intwhat, intextra) {
                    switch(what) {
                        caseIMediaPlayer.MEDIA_INFO_BUFFERING_START:
                            statusChange(STATUS_LOADING);
                            break;
                        caseIMediaPlayer.MEDIA_INFO_BUFFERING_END:
                            statusChange(STATUS_PLAYING);
                            break;
                        caseIMediaPlayer.MEDIA_INFO_NETWORK_BANDWIDTH:
                            //显示下载速度
    //                      Toast.show("download rate:" + extra);
                            break;
                        caseIMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START:
                            statusChange(STATUS_PLAYING);
                            break;
                    }
                    onInfoListener.onInfo(what,extra);
                    returnfalse;
                }
            });
     
            audioManager = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
            mMaxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
            gestureDetector = newGestureDetector(activity, newPlayerGestureListener());
     
            if(fullScreenOnly) {
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            }
            portrait=getScreenOrientation()== ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
     
            if(!playerSupport) {
                DebugLog.e("播放器不支持此设备");
            }
        }
     
        privatevoid statusChange(intnewStatus) {
            status = newStatus;
            if(!isLive && newStatus==STATUS_COMPLETED) {
                DebugLog.d("statusChange STATUS_COMPLETED...");
                if(playerStateListener != null){
                    playerStateListener.onComplete();
                }
            }elseif (newStatus == STATUS_ERROR) {
                DebugLog.d("statusChange STATUS_ERROR...");
                if(playerStateListener != null){
                    playerStateListener.onError();
                }
            }elseif(newStatus==STATUS_LOADING){
    //            $.id(R.id.app_video_loading).visible();
                if(playerStateListener != null){
                    playerStateListener.onLoading();
                }
                DebugLog.d("statusChange STATUS_LOADING...");
            }elseif (newStatus == STATUS_PLAYING) {
                DebugLog.d("statusChange STATUS_PLAYING...");
                if(playerStateListener != null){
                    playerStateListener.onPlay();
                }
            }
        }
     
        publicvoid onPause() {
            pauseTime= System.currentTimeMillis();
            if(status==STATUS_PLAYING) {
                videoView.pause();
                if(!isLive) {
                    currentPosition = videoView.getCurrentPosition();
                }
            }
        }
     
        publicvoid onResume() {
            pauseTime=0;
            if(status==STATUS_PLAYING) {
                if(isLive) {
                    videoView.seekTo(0);
                }else{
                    if(currentPosition>0) {
                        videoView.seekTo(currentPosition);
                    }
                }
                videoView.start();
            }
        }
     
        publicvoid onDestroy() {
            orientationEventListener.disable();
            videoView.stopPlayback();
        }
     
        publicvoid play(String url) {
            this.url = url;
            if(playerSupport) {
                videoView.setVideoPath(url);
                videoView.start();
            }
        }
     
        privateString generateTime(longtime) {
            inttotalSeconds = (int) (time / 1000);
            intseconds = totalSeconds % 60;
            intminutes = (totalSeconds / 60) % 60;
            inthours = totalSeconds / 3600;
            returnhours > 0? String.format("%02d:%02d:%02d", hours, minutes, seconds) : String.format("%02d:%02d", minutes, seconds);
        }
     
        privateint getScreenOrientation() {
            introtation = activity.getWindowManager().getDefaultDisplay().getRotation();
            DisplayMetrics dm = newDisplayMetrics();
            activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
            intwidth = dm.widthPixels;
            intheight = dm.heightPixels;
            intorientation;
            // if the device's natural orientation is portrait:
            if((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) && height > width ||
                    (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) && width > height) {
                switch(rotation) {
                    caseSurface.ROTATION_0:
                        orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
                        break;
                    caseSurface.ROTATION_90:
                        orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
                        break;
                    caseSurface.ROTATION_180:
                        orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
                        break;
                    caseSurface.ROTATION_270:
                        orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
                        break;
                    default:
                        orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
                        break;
                }
            }
            // if the device's natural orientation is landscape or if the device
            // is square:
            else{
                switch(rotation) {
                    caseSurface.ROTATION_0:
                        orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
                        break;
                    caseSurface.ROTATION_90:
                        orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
                        break;
                    caseSurface.ROTATION_180:
                        orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
                        break;
                    caseSurface.ROTATION_270:
                        orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
                        break;
                    default:
                        orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
                        break;
                }
            }
            returnorientation;
        }
     
        /**
         * 滑动改变声音大小
         *
         * @param percent
         */
        privatevoid onVolumeSlide(floatpercent) {
            if(volume == -1) {
                volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
                if(volume < 0)
                    volume = 0;
            }
            intindex = (int) (percent * mMaxVolume) + volume;
            if(index > mMaxVolume) {
                index = mMaxVolume;
            }elseif (index < 0){
                index = 0;
            }
            // 变更声音
            audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);
            // 变更进度条
            inti = (int) (index * 1.0/ mMaxVolume * 100);
            String s = i + "%";
            if(i == 0) {
                s = "off";
            }
            DebugLog.d("onVolumeSlide:"+s);
        }
     
        privatevoid onProgressSlide(floatpercent) {
            longposition = videoView.getCurrentPosition();
            longduration = videoView.getDuration();
            longdeltaMax = Math.min(100* 1000, duration - position);
            longdelta = (long) (deltaMax * percent);
     
            newPosition = delta + position;
            if(newPosition > duration) {
                newPosition = duration;
            }elseif (newPosition <= 0) {
                newPosition=0;
                delta=-position;
            }
            intshowDelta = (int) delta / 1000;
            if(showDelta != 0) {
                String text = showDelta > 0? ("+"+ showDelta) : ""+ showDelta;
                DebugLog.d("onProgressSlide:"+ text);
            }
        }
     
        /**
         * 滑动改变亮度
         *
         * @param percent
         */
        privatevoid onBrightnessSlide(floatpercent) {
            if(brightness < 0) {
                brightness = activity.getWindow().getAttributes().screenBrightness;
                if(brightness <= 0.00f){
                    brightness = 0.50f;
                }elseif (brightness < 0.01f){
                    brightness = 0.01f;
                }
            }
            DebugLog.d("brightness:"+brightness+",percent:"+ percent);
            WindowManager.LayoutParams lpa = activity.getWindow().getAttributes();
            lpa.screenBrightness = brightness + percent;
            if(lpa.screenBrightness > 1.0f){
                lpa.screenBrightness = 1.0f;
            }elseif (lpa.screenBrightness < 0.01f){
                lpa.screenBrightness = 0.01f;
            }
            activity.getWindow().setAttributes(lpa);
        }
     
        publicvoid setFullScreenOnly(booleanfullScreenOnly) {
            this.fullScreenOnly = fullScreenOnly;
            tryFullScreen(fullScreenOnly);
            if(fullScreenOnly) {
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            }else{
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
            }
        }
     
        privatevoid tryFullScreen(booleanfullScreen) {
            if(activity instanceofAppCompatActivity) {
                ActionBar supportActionBar = ((AppCompatActivity) activity).getSupportActionBar();
                if(supportActionBar != null) {
                    if(fullScreen) {
                        supportActionBar.hide();
                    }else{
                        supportActionBar.show();
                    }
                }
            }
            setFullScreen(fullScreen);
        }
     
        privatevoid setFullScreen(booleanfullScreen) {
            if(activity != null) {
                WindowManager.LayoutParams attrs = activity.getWindow().getAttributes();
                if(fullScreen) {
                    attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
                    activity.getWindow().setAttributes(attrs);
                    activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
                }else{
                    attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
                    activity.getWindow().setAttributes(attrs);
                    activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
                }
            }
        }
     
        /**
         *
    ?
    1
    * fitParent:可能会剪裁,保持原视频的大小,显示在中心,当原视频的大小超过view的大小超过部分裁剪处理 * fillParent:可能会剪裁,等比例放大视频,直到填满View为止,超过View的部分作裁剪处理 * wrapContent:将视频的内容完整居中显示,如果视频大于view,则按比例缩视频直到完全显示在view中 * fitXY:不剪裁,非等比例拉伸画面填满整个View *16:9:不剪裁,非等比例拉伸画面到16:9,并完全显示在View中 * 4:3:不剪裁,非等比例拉伸画面到4:3,并完全显示在View中 *
    * @param scaleType */ public void setScaleType(String scaleType) { if (SCALETYPE_FITPARENT.equals(scaleType)) { videoView.setAspectRatio(IRenderView.AR_ASPECT_FIT_PARENT); }else if (SCALETYPE_FILLPARENT.equals(scaleType)) { videoView.setAspectRatio(IRenderView.AR_ASPECT_FILL_PARENT); }else if (SCALETYPE_WRAPCONTENT.equals(scaleType)) { videoView.setAspectRatio(IRenderView.AR_ASPECT_WRAP_CONTENT); }else if (SCALETYPE_FITXY.equals(scaleType)) { videoView.setAspectRatio(IRenderView.AR_MATCH_PARENT); }else if (SCALETYPE_16_9.equals(scaleType)) { videoView.setAspectRatio(IRenderView.AR_16_9_FIT_PARENT); }else if (SCALETYPE_4_3.equals(scaleType)) { videoView.setAspectRatio(IRenderView.AR_4_3_FIT_PARENT); } } public void start() { videoView.start(); } public void pause() { videoView.pause(); } public boolean onBackPressed() { if (!fullScreenOnly && getScreenOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); return true; } return false; } class Query { private final Activity activity; private View view; public Query(Activity activity) { this.activity=activity; } public Query id(int id) { view = activity.findViewById(id); return this; } public Query image(int resId) { if (view instanceof ImageView) { ((ImageView) view).setImageResource(resId); } return this; } public Query visible() { if (view != null) { view.setVisibility(View.VISIBLE); } return this; } public Query gone() { if (view != null) { view.setVisibility(View.GONE); } return this; } public Query invisible() { if (view != null) { view.setVisibility(View.INVISIBLE); } return this; } public Query clicked(View.OnClickListener handler) { if (view != null) { view.setOnClickListener(handler); } return this; } public Query text(CharSequence text) { if (view!=null && view instanceof TextView) { ((TextView) view).setText(text); } return this; } public Query visibility(int visible) { if (view != null) { view.setVisibility(visible); } return this; } private void size(boolean width, int n, boolean dip){ if(view != null){ ViewGroup.LayoutParams lp = view.getLayoutParams(); if(n > 0 && dip){ n = dip2pixel(activity, n); } if(width){ lp.width = n; }else{ lp.height = n; } view.setLayoutParams(lp); } } public void height(int height, boolean dip) { size(false,height,dip); } public int dip2pixel(Context context, float n){ int value = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, n, context.getResources().getDisplayMetrics()); return value; } public float pixel2dip(Context context, float n){ Resources resources = context.getResources(); DisplayMetrics metrics = resources.getDisplayMetrics(); float dp = n / (metrics.densityDpi / 160f); return dp; } } public class PlayerGestureListener extends GestureDetector.SimpleOnGestureListener { private boolean firstTouch; private boolean volumeControl; private boolean toSeek; /** * 双击 */ @Override public boolean onDoubleTap(MotionEvent e) { videoView.toggleAspectRatio(); return true; } @Override public boolean onDown(MotionEvent e) { firstTouch = true; return super.onDown(e); } /** * 滑动 */ @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { float mOldX = e1.getX(), mOldY = e1.getY(); float deltaY = mOldY - e2.getY(); float deltaX = mOldX - e2.getX(); if (firstTouch) { toSeek = Math.abs(distanceX) >= Math.abs(distanceY); volumeControl=mOldX > screenWidthPixels * 0.5f; firstTouch = false; } if (toSeek) { if (!isLive) { onProgressSlide(-deltaX / videoView.getWidth()); } } else { float percent = deltaY / videoView.getHeight(); if (volumeControl) { onVolumeSlide(percent); } else { onBrightnessSlide(percent); } } return super.onScroll(e1, e2, distanceX, distanceY); } @Override public boolean onSingleTapUp(MotionEvent e) { return true; } } /** * is player support this device * @return */ public boolean isPlayerSupport() { return playerSupport; } /** * 是否正在播放 * @return */ public boolean isPlaying() { return videoView!=null?videoView.isPlaying():false; } public void stop(){ videoView.stopPlayback(); } public int getCurrentPosition(){ return videoView.getCurrentPosition(); } /** * get video duration * @return */ public int getDuration(){ return videoView.getDuration(); } public PlayerManager playInFullScreen(boolean fullScreen){ if (fullScreen) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } return this; } public PlayerManager onError(OnErrorListener onErrorListener) { this.onErrorListener = onErrorListener; return this; } public PlayerManager onComplete(OnCompleteListener onCompleteListener) { this.onCompleteListener = onCompleteListener; return this; } public PlayerManager onInfo(OnInfoListener onInfoListener) { this.onInfoListener = onInfoListener; return this; } public PlayerManager onControlPanelVisibilityChange(OnControlPanelVisibilityChangeListener listener){ this.onControlPanelVisibilityChangeListener = listener; return this; } /** * set is live (can't seek forward) * @param isLive * @return */ public PlayerManager live(boolean isLive) { this.isLive = isLive; return this; } public PlayerManager toggleAspectRatio(){ if (videoView != null) { videoView.toggleAspectRatio(); } return this; } public interface PlayerStateListener{ void onComplete(); void onError(); void onLoading(); void onPlay(); } public interface OnErrorListener{ void onError(int what, int extra); } public interface OnCompleteListener{ void onComplete(); } public interface OnControlPanelVisibilityChangeListener{ void change(boolean isShowing); } public interface OnInfoListener{ void onInfo(int what, int extra); } }

    使用封装后的PlayerManager播放视频:

    ?
    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
    publicclass MainActivity extendsAppCompatActivity implementsPlayerManager.PlayerStateListener{
        privateString url1 = "rtmp://203.207.99.19:1935/live/CCTV5";
        privateString url2 = "http://zv.3gv.ifeng.com/live/zhongwen800k.m3u8";
        privateString url3 = "rtsp://184.72.239.149/vod/mp4:BigBuckBunny_115k.mov";
        privateString url4 = "http://42.96.249.166/live/24035.m3u8";
        privatePlayerManager player;
     
        @Override
        protectedvoid onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initPlayer();
        }
     
        privatevoid initPlayer() {
            player = newPlayerManager(this);
            player.setFullScreenOnly(true);
            player.setScaleType(PlayerManager.SCALETYPE_FILLPARENT);
            player.playInFullScreen(true);
            player.setPlayerStateListener(this);
            player.play(url1);
        }
     
        @Override
        publicboolean onTouchEvent(MotionEvent event) {
            if(player.gestureDetector.onTouchEvent(event))
                returntrue;
            returnsuper.onTouchEvent(event);
        }
     
        @Override
        publicvoid onComplete() {
        }
     
        @Override
        publicvoid onError() {
        }
     
        @Override
        publicvoid onLoading() {
        }
     
        @Override
        publicvoid onPlay() {
        }
    }

    Demo下载地


  • 原创粉丝点击