├── .idea
├── .name
├── copyright
│ └── profiles_settings.xml
├── vcs.xml
├── modules.xml
├── runConfigurations.xml
├── gradle.xml
├── compiler.xml
└── misc.xml
├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── drawable
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ └── styles.xml
│ │ │ ├── values-w820dp
│ │ │ │ └── dimens.xml
│ │ │ ├── menu
│ │ │ │ └── menu_main.xml
│ │ │ └── layout
│ │ │ │ ├── frament_list.xml
│ │ │ │ ├── activity_viewpager.xml
│ │ │ │ ├── activity_main.xml
│ │ │ │ ├── activity_list.xml
│ │ │ │ └── activity_play.xml
│ │ ├── java
│ │ │ └── js
│ │ │ │ └── listvideodemo
│ │ │ │ ├── Utils.java
│ │ │ │ ├── ImageLoaderOptions.java
│ │ │ │ ├── viewpager
│ │ │ │ ├── VideoFramentAdapter.java
│ │ │ │ ├── ViewPagerActivity.java
│ │ │ │ └── ListVideoFrament.java
│ │ │ │ ├── VideoApplication.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── list
│ │ │ │ ├── ListVideoAdapter.java
│ │ │ │ └── ListActivity.java
│ │ │ │ └── playpage
│ │ │ │ └── PlayPageActivity.java
│ │ └── AndroidManifest.xml
│ └── androidTest
│ │ └── java
│ │ └── js
│ │ └── listvideodemo
│ │ └── ApplicationTest.java
├── proguard-rules.pro
├── build.gradle
└── app.iml
├── ListVideoPlay
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── drawable-xhdpi
│ │ │ ├── uu_back.png
│ │ │ ├── icon_back_2.png
│ │ │ ├── icon_more.png
│ │ │ ├── icon_more_h.png
│ │ │ ├── uu_enlarge.png
│ │ │ ├── uu_shrink.png
│ │ │ ├── icon_share_2.png
│ │ │ ├── uu_loading_bg.png
│ │ │ ├── icon_share_2_h.png
│ │ │ ├── sound_open_icon.png
│ │ │ ├── uu_backward_icon.png
│ │ │ ├── uu_error_normal.png
│ │ │ ├── uu_error_pressed.png
│ │ │ ├── uu_forward_icon.png
│ │ │ ├── uu_pause_normal.png
│ │ │ ├── uu_pause_pressed.png
│ │ │ ├── uu_play_normal.png
│ │ │ ├── uu_play_pressed.png
│ │ │ ├── uu_volume_icon.png
│ │ │ └── video_stop_btn.png
│ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ ├── values
│ │ │ ├── dimens.xml
│ │ │ ├── styles.xml
│ │ │ └── strings.xml
│ │ ├── drawable
│ │ │ ├── uu_loading.xml
│ │ │ ├── uu_seek_thumb_normal.xml
│ │ │ ├── uu_seek_thumb_pressed.xml
│ │ │ ├── background_title.xml
│ │ │ ├── uu_seek_thumb.xml
│ │ │ ├── more_selector.xml
│ │ │ ├── shape_selector.xml
│ │ │ ├── uu_dialog_progress_bg.xml
│ │ │ ├── uu_time.xml
│ │ │ ├── uu_dialog_progress.xml
│ │ │ ├── uu_volume_progress_bg.xml
│ │ │ ├── uu_seek_progress.xml
│ │ │ └── uu_progress.xml
│ │ └── layout
│ │ │ ├── table_media_info.xml
│ │ │ ├── table_media_info_section.xml
│ │ │ ├── table_media_info_row1.xml
│ │ │ ├── table_media_info_row2.xml
│ │ │ ├── uu_volume_dialog.xml
│ │ │ ├── view_video_item.xml
│ │ │ ├── uu_progress_dialog.xml
│ │ │ ├── media_contoller.xml
│ │ │ └── item_video.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── js
│ │ └── nch
│ │ └── videoplay
│ │ ├── VideoPlayViewManage.java
│ │ ├── video
│ │ ├── IMediaController.java
│ │ ├── MediaPlayerService.java
│ │ ├── IRenderView.java
│ │ ├── MediaPlayerCompat.java
│ │ ├── TableLayoutBinder.java
│ │ ├── Settings.java
│ │ ├── InfoHudViewHolder.java
│ │ ├── SurfaceRenderView.java
│ │ └── MeasureHelper.java
│ │ ├── Utils.java
│ │ ├── VideoPlayView.java
│ │ └── FullScreenTouch.java
├── proguard-rules.pro
├── build.gradle
├── ListVideoPlay.iml
└── app.iml
├── settings.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── README.md
├── gradle.properties
├── VideoList.iml
├── ListVideoDemo2.iml
├── gradlew.bat
└── gradlew
/.idea/.name:
--------------------------------------------------------------------------------
1 | VideoList
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/ListVideoPlay/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':ListVideoPlay'
2 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | /local.properties
3 | /.idea/workspace.xml
4 | /.idea/libraries
5 | .DS_Store
6 | /build
7 | /captures
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # VideoListCase
2 | 基于ijkplayer的视频播放列表,支持列表播放、全屏播放(加减声音、进度条)、经典viewpage+fragment组合的列表播放、正在播放视频拖动到不可见区域小窗口播放、无缝列表页进播放继续播放
3 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/app/src/main/res/drawable/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/uu_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/uu_back.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/icon_back_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/icon_back_2.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/icon_more.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/icon_more.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/icon_more_h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/icon_more_h.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/uu_enlarge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/uu_enlarge.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/uu_shrink.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/uu_shrink.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/icon_share_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/icon_share_2.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/uu_loading_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/uu_loading_bg.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/icon_share_2_h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/icon_share_2_h.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/sound_open_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/sound_open_icon.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/uu_backward_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/uu_backward_icon.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/uu_error_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/uu_error_normal.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/uu_error_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/uu_error_pressed.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/uu_forward_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/uu_forward_icon.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/uu_pause_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/uu_pause_normal.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/uu_pause_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/uu_pause_pressed.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/uu_play_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/uu_play_normal.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/uu_play_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/uu_play_pressed.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/uu_volume_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/uu_volume_icon.png
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable-xhdpi/video_stop_btn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/707813227/VideoListCase/HEAD/ListVideoPlay/src/main/res/drawable-xhdpi/video_stop_btn.png
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 80dp
3 | 24dp
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ListVideoDemo
3 |
4 | Hello world!
5 | Settings
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Aug 31 16:14:56 CST 2016
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
7 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable/uu_loading.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable/uu_seek_thumb_normal.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable/uu_seek_thumb_pressed.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable/background_title.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable/uu_seek_thumb.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable/more_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable/shape_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable/uu_dialog_progress_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/java/js/listvideodemo/Utils.java:
--------------------------------------------------------------------------------
1 | package js.listvideodemo;
2 |
3 | /**
4 | * Created by peter on 16/8/31.
5 | */
6 | public class Utils {
7 |
8 | private static int videoHeight;
9 |
10 | public static void setVideoHeight(int videoHeight) {
11 | Utils.videoHeight = videoHeight;
12 | }
13 |
14 | public static int getVideoHeight() {
15 | return videoHeight;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable/uu_time.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | xmlns:android="http//schemas.android.com/apk/res/android"
4 | android:shape="oval">
5 |
6 |
7 |
8 |
9 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/js/listvideodemo/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package js.listvideodemo;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/frament_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/layout/table_media_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/layout/table_media_info_section.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable/uu_dialog_progress.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable/uu_volume_progress_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 | -
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/peter/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ListVideoPlay/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/peter/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/layout/table_media_info_row1.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
20 |
21 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/java/js/listvideodemo/ImageLoaderOptions.java:
--------------------------------------------------------------------------------
1 | package js.listvideodemo;
2 |
3 | import com.nostra13.universalimageloader.core.DisplayImageOptions;
4 | import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
5 |
6 | /**
7 | * Created by peter on 16/8/31.
8 | */
9 | public class ImageLoaderOptions {
10 |
11 | // 在listview中使用的设置
12 | public static DisplayImageOptions list_options = new DisplayImageOptions.Builder()
13 | .showImageOnLoading(R.drawable.ic_launcher)
14 | .showImageForEmptyUri(R.drawable.ic_launcher)
15 | .showImageOnFail(R.drawable.ic_launcher)
16 | .cacheInMemory(true)
17 | .cacheOnDisk(true).considerExifParams(true)// 会识别图片的方向信息
18 | .displayer(new FadeInBitmapDisplayer(0)).build();// 渐渐显示的动画
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/layout/table_media_info_row2.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
23 |
24 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/java/js/nch/videoplay/VideoPlayViewManage.java:
--------------------------------------------------------------------------------
1 | package js.nch.videoplay;
2 |
3 | import android.content.Context;
4 |
5 | /**
6 | * Created by peter on 16/8/31.
7 | */
8 | public class VideoPlayViewManage {
9 | public static VideoPlayViewManage videoPlayViewManage ;
10 | private VideoPlayView videoPlayView;
11 | private VideoPlayViewManage(){
12 |
13 | }
14 | public static VideoPlayViewManage getManage(){
15 | if (videoPlayViewManage == null){
16 | videoPlayViewManage = new VideoPlayViewManage();
17 | }
18 | return videoPlayViewManage;
19 | }
20 |
21 | public VideoPlayView initialize(Context context){
22 | if (videoPlayView ==null){
23 | videoPlayView = new VideoPlayView(context);
24 | }else {
25 | videoPlayView.setContext(context);
26 | }
27 | return videoPlayView;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/ListVideoPlay/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.1"
6 |
7 | defaultConfig {
8 | minSdkVersion 15
9 | targetSdkVersion 23
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | compile fileTree(dir: 'libs', include: ['*.jar'])
23 | compile 'com.android.support:appcompat-v7:24.0.0'
24 | compile 'tv.danmaku.ijk.media:ijkplayer-java:0.6.0'
25 | compile 'tv.danmaku.ijk.media:ijkplayer-exo:0.6.0'
26 | compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.6.0'
27 | compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.6.0'
28 | compile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.6.0'
29 | }
30 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable/uu_seek_progress.xml:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/drawable/uu_progress.xml:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.1"
6 |
7 | defaultConfig {
8 | applicationId "js.listvideodemo"
9 | minSdkVersion 15
10 | targetSdkVersion 23
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | compile 'com.android.support:appcompat-v7:24.0.0'
25 | compile 'com.android.support:design:24.0.0'
26 | compile 'com.android.support:cardview-v7:23.2.1'
27 | compile 'com.android.support:recyclerview-v7:23.2.1'
28 |
29 | compile project(':ListVideoPlay')
30 | compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.4'
31 | }
32 |
--------------------------------------------------------------------------------
/VideoList.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ListVideoDemo2.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/layout/uu_volume_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
21 |
22 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_viewpager.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
10 |
16 |
20 |
21 |
22 |
23 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/java/js/nch/videoplay/video/IMediaController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Zhang Rui
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package js.nch.videoplay.video;
18 |
19 | import android.view.View;
20 | import android.widget.MediaController;
21 |
22 | public interface IMediaController {
23 | void hide();
24 |
25 | boolean isShowing();
26 |
27 | void setAnchorView(View view);
28 |
29 | void setEnabled(boolean enabled);
30 |
31 | void setMediaPlayer(MediaController.MediaPlayerControl player);
32 |
33 | void show(int timeout);
34 |
35 | void show();
36 |
37 | //----------
38 | // Extends
39 | //----------
40 | void showOnce(View view);
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/js/listvideodemo/viewpager/VideoFramentAdapter.java:
--------------------------------------------------------------------------------
1 | package js.listvideodemo.viewpager;
2 |
3 | import android.support.v4.app.Fragment;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v4.app.FragmentStatePagerAdapter;
6 |
7 | import java.util.ArrayList;
8 |
9 | import js.nch.videoplay.VideoPlayView;
10 |
11 | /**
12 | * Created by peter on 16/8/31.
13 | */
14 | public class VideoFramentAdapter extends FragmentStatePagerAdapter {
15 | private ViewPagerActivity viewPagerActivity;
16 | private VideoPlayView videoPlayView;
17 | private ArrayList data;
18 |
19 | public VideoFramentAdapter(ViewPagerActivity viewPagerActivity, FragmentManager fm, ArrayList data, VideoPlayView videoPlayView) {
20 | super(fm);
21 | this.data = data;
22 | this.videoPlayView = videoPlayView;
23 | this.viewPagerActivity = viewPagerActivity;
24 | }
25 |
26 | @Override
27 | public Fragment getItem(int position) {
28 | return new ListVideoFrament(viewPagerActivity,videoPlayView);
29 | }
30 |
31 | @Override
32 | public int getCount() {
33 | return data.size();
34 | }
35 |
36 | @Override
37 | public CharSequence getPageTitle(int position) {
38 | return data.get(position);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
9 |
14 |
20 |
25 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
14 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/java/js/listvideodemo/VideoApplication.java:
--------------------------------------------------------------------------------
1 | package js.listvideodemo;
2 |
3 | import android.app.Application;
4 | import android.os.Handler;
5 |
6 | import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
7 | import com.nostra13.universalimageloader.core.ImageLoader;
8 | import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
9 | import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
10 |
11 | /**
12 | * Created by peter on 16/8/31.
13 | */
14 | public class VideoApplication extends Application {
15 | private static Handler mHandler = new Handler();;
16 | @Override
17 | public void onCreate() {
18 | initUniversalImageLoader();
19 | }
20 | public static Handler getMainHandler(){
21 | return mHandler;
22 | }
23 | /**
24 | * 初始化ImageLoader
25 | */
26 | private void initUniversalImageLoader() {
27 | ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(this);
28 | config.threadPriority(Thread.NORM_PRIORITY - 2);
29 | config.denyCacheImageMultipleSizesInMemory();
30 | config.diskCacheFileNameGenerator(new Md5FileNameGenerator());
31 | config.diskCacheSize(50 * 1024 * 1024); // 50 MiB
32 | config.tasksProcessingOrder(QueueProcessingType.LIFO);
33 | config.writeDebugLogs(); // Remove for releaseAllVideos app
34 | // config.defaultDisplayImageOptions(getDefaultDisplayImageOption());
35 | // Initialize ImageLoader with configuration.
36 | ImageLoader.getInstance().init(config.build());
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/java/js/nch/videoplay/Utils.java:
--------------------------------------------------------------------------------
1 | package js.nch.videoplay;
2 | import android.content.Context;
3 | import android.net.ConnectivityManager;
4 | import android.net.NetworkInfo;
5 |
6 | import java.util.Formatter;
7 | import java.util.Locale;
8 |
9 | public class Utils {
10 |
11 | public static String stringForTime(int timeMs) {
12 | if (timeMs <= 0 || timeMs >= 24 * 60 * 60 * 1000) {
13 | return "00:00";
14 | }
15 | int totalSeconds = timeMs / 1000;
16 | int seconds = totalSeconds % 60;
17 | int minutes = (totalSeconds / 60) % 60;
18 | int hours = totalSeconds / 3600;
19 | StringBuilder stringBuilder = new StringBuilder();
20 | Formatter mFormatter = new Formatter(stringBuilder, Locale.getDefault());
21 | if (hours > 0) {
22 | return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();
23 | } else {
24 | return mFormatter.format("%02d:%02d", minutes, seconds).toString();
25 | }
26 | }
27 |
28 | public static boolean isWifiConnected(Context context) {
29 | ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
30 | NetworkInfo wifiNetworkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
31 | if (wifiNetworkInfo.isConnected()) {
32 | return true;
33 | }
34 | return false;
35 | }
36 |
37 | public static int dip2px(Context context ,int dpValue){
38 | // 获取密度比
39 | float density = context.getResources().getDisplayMetrics().density;
40 | int px = (int) (density * dpValue + 0.5f);
41 | return px;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
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 | 1.8
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/java/js/listvideodemo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package js.listvideodemo;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 | import android.view.View;
8 | import android.view.WindowManager;
9 |
10 | import js.listvideodemo.list.ListActivity;
11 | import js.listvideodemo.small.ListSmallActivity;
12 | import js.listvideodemo.viewpager.ViewPagerActivity;
13 |
14 | public class MainActivity extends Activity {
15 |
16 | @Override
17 | protected void onCreate(Bundle savedInstanceState) {
18 | super.onCreate(savedInstanceState);
19 | setContentView(R.layout.activity_main);
20 |
21 | WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
22 | int windowWith = (int) (wm.getDefaultDisplay().getWidth() * 0.5652f);
23 | Utils.setVideoHeight(windowWith);
24 |
25 | findViewById(R.id.list).setOnClickListener(new View.OnClickListener() {
26 | @Override
27 | public void onClick(View v) {
28 | startActivity(new Intent(MainActivity.this,ListActivity.class));
29 | }
30 | });
31 | findViewById(R.id.list_vp).setOnClickListener(new View.OnClickListener() {
32 | @Override
33 | public void onClick(View v) {
34 | startActivity(new Intent(MainActivity.this,ViewPagerActivity.class));
35 | }
36 | });
37 | findViewById(R.id.list_small).setOnClickListener(new View.OnClickListener() {
38 | @Override
39 | public void onClick(View v) {
40 | startActivity(new Intent(MainActivity.this,ListSmallActivity.class));
41 | }
42 | });
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/layout/view_video_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
23 |
31 |
36 |
37 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
25 |
29 |
33 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/layout/uu_progress_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
19 |
20 |
27 |
28 |
34 |
35 |
41 |
42 |
43 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/java/js/nch/videoplay/video/MediaPlayerService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Zhang Rui
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package js.nch.videoplay.video;
18 |
19 | import android.app.Service;
20 | import android.content.Context;
21 | import android.content.Intent;
22 | import android.os.IBinder;
23 | import android.support.annotation.Nullable;
24 |
25 | import tv.danmaku.ijk.media.player.IMediaPlayer;
26 |
27 | public class MediaPlayerService extends Service {
28 | private static IMediaPlayer sMediaPlayer;
29 |
30 | public static Intent newIntent(Context context) {
31 | Intent intent = new Intent(context, MediaPlayerService.class);
32 | return intent;
33 | }
34 |
35 | public static void intentToStart(Context context) {
36 | context.startService(newIntent(context));
37 | }
38 |
39 | public static void intentToStop(Context context) {
40 | context.stopService(newIntent(context));
41 | }
42 |
43 | @Nullable
44 | @Override
45 | public IBinder onBind(Intent intent) {
46 | return null;
47 | }
48 |
49 | public static void setMediaPlayer(IMediaPlayer mp) {
50 | if (sMediaPlayer != null && sMediaPlayer != mp) {
51 | if (sMediaPlayer.isPlaying())
52 | sMediaPlayer.stop();
53 | sMediaPlayer.release();
54 | sMediaPlayer = null;
55 | }
56 | sMediaPlayer = mp;
57 | }
58 |
59 | public static IMediaPlayer getMediaPlayer() {
60 | return sMediaPlayer;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
19 |
20 |
24 |
25 |
32 |
33 |
34 |
35 |
42 |
47 |
48 |
49 |
50 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_play.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
17 |
18 |
22 |
23 |
24 |
25 |
31 |
32 |
41 |
42 |
47 |
48 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
66 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/java/js/nch/videoplay/video/IRenderView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Zhang Rui
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package js.nch.videoplay.video;
18 |
19 | import android.graphics.SurfaceTexture;
20 | import android.support.annotation.NonNull;
21 | import android.support.annotation.Nullable;
22 | import android.view.Surface;
23 | import android.view.SurfaceHolder;
24 | import android.view.View;
25 |
26 | import tv.danmaku.ijk.media.player.IMediaPlayer;
27 |
28 | public interface IRenderView {
29 | int AR_ASPECT_FIT_PARENT = 0; // without clip
30 | int AR_ASPECT_FILL_PARENT = 1; // may clip
31 | int AR_ASPECT_WRAP_CONTENT = 2;
32 | int AR_MATCH_PARENT = 3;
33 | int AR_16_9_FIT_PARENT = 4;
34 | int AR_4_3_FIT_PARENT = 5;
35 |
36 | View getView();
37 |
38 | boolean shouldWaitForResize();
39 |
40 | void setVideoSize(int videoWidth, int videoHeight);
41 |
42 | void setVideoSampleAspectRatio(int videoSarNum, int videoSarDen);
43 |
44 | void setVideoRotation(int degree);
45 |
46 | void setAspectRatio(int aspectRatio);
47 |
48 | void addRenderCallback(@NonNull IRenderCallback callback);
49 |
50 | void removeRenderCallback(@NonNull IRenderCallback callback);
51 |
52 | interface ISurfaceHolder {
53 | void bindToMediaPlayer(IMediaPlayer mp);
54 |
55 | @NonNull
56 | IRenderView getRenderView();
57 |
58 | @Nullable
59 | SurfaceHolder getSurfaceHolder();
60 |
61 | @Nullable
62 | Surface openSurface();
63 |
64 | @Nullable
65 | SurfaceTexture getSurfaceTexture();
66 | }
67 |
68 | interface IRenderCallback {
69 | /**
70 | * @param holder
71 | * @param width could be 0
72 | * @param height could be 0
73 | */
74 | void onSurfaceCreated(@NonNull ISurfaceHolder holder, int width, int height);
75 |
76 | /**
77 | * @param holder
78 | * @param format could be 0
79 | * @param width
80 | * @param height
81 | */
82 | void onSurfaceChanged(@NonNull ISurfaceHolder holder, int format, int width, int height);
83 |
84 | void onSurfaceDestroyed(@NonNull ISurfaceHolder holder);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/java/js/nch/videoplay/video/MediaPlayerCompat.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Zhang Rui
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package js.nch.videoplay.video;
18 |
19 | import tv.danmaku.ijk.media.player.IMediaPlayer;
20 | import tv.danmaku.ijk.media.player.IjkMediaPlayer;
21 | import tv.danmaku.ijk.media.player.MediaPlayerProxy;
22 | import tv.danmaku.ijk.media.player.TextureMediaPlayer;
23 |
24 | public class MediaPlayerCompat {
25 | public static String getName(IMediaPlayer mp) {
26 | if (mp == null) {
27 | return "null";
28 | } else if (mp instanceof TextureMediaPlayer) {
29 | StringBuilder sb = new StringBuilder("TextureMediaPlayer <");
30 | IMediaPlayer internalMediaPlayer = ((TextureMediaPlayer) mp).getInternalMediaPlayer();
31 | if (internalMediaPlayer == null) {
32 | sb.append("null>");
33 | } else {
34 | sb.append(internalMediaPlayer.getClass().getSimpleName());
35 | sb.append(">");
36 | }
37 | return sb.toString();
38 | } else {
39 | return mp.getClass().getSimpleName();
40 | }
41 | }
42 |
43 | public static IjkMediaPlayer getIjkMediaPlayer(IMediaPlayer mp) {
44 | IjkMediaPlayer ijkMediaPlayer = null;
45 | if (mp == null) {
46 | return null;
47 | } if (mp instanceof IjkMediaPlayer) {
48 | ijkMediaPlayer = (IjkMediaPlayer) mp;
49 | } else if (mp instanceof MediaPlayerProxy && ((MediaPlayerProxy) mp).getInternalMediaPlayer() instanceof IjkMediaPlayer) {
50 | ijkMediaPlayer = (IjkMediaPlayer) ((MediaPlayerProxy) mp).getInternalMediaPlayer();
51 | }
52 | return ijkMediaPlayer;
53 | }
54 |
55 | public static void selectTrack(IMediaPlayer mp, int stream) {
56 | IjkMediaPlayer ijkMediaPlayer = getIjkMediaPlayer(mp);
57 | if (ijkMediaPlayer == null)
58 | return;
59 | ijkMediaPlayer.selectTrack(stream);
60 | }
61 |
62 | public static void deselectTrack(IMediaPlayer mp, int stream) {
63 | IjkMediaPlayer ijkMediaPlayer = getIjkMediaPlayer(mp);
64 | if (ijkMediaPlayer == null)
65 | return;
66 | ijkMediaPlayer.deselectTrack(stream);
67 | }
68 |
69 | public static int getSelectedTrack(IMediaPlayer mp, int trackType) {
70 | IjkMediaPlayer ijkMediaPlayer = getIjkMediaPlayer(mp);
71 | if (ijkMediaPlayer == null)
72 | return -1;
73 | return ijkMediaPlayer.getSelectedTrack(trackType);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ListVideoPlay
3 |
4 | Render: None
5 | Render: SurfaceView
6 | Render: TextureView
7 | N/A
8 | Close
9 | Exit
10 | Sample
11 | Recent
12 | Settings
13 | Tracks
14 | Player
15 | Render
16 | Scale
17 | Info
18 | vdec
19 | fps
20 | v-cache
21 | a-cache
22 |
23 | Aspect / Fit parent
24 | Aspect / Fill parent
25 | Aspect / Wrap content
26 | Free / Fill parent
27 | 16:9 / Fit parent
28 | 4:3 / Fit parent
29 |
30 | pref.enable_background_play
31 | Enable background play
32 | need Android 4.0+
33 | pref.player
34 | pref.using_media_codec
35 | pref.using_media_codec_auto_rotate
36 | pref.using_opensl_es
37 | pref.pixel_format
38 | pref.enable_no_view
39 | pref.enable_surface_view
40 | pref.enable_texture_view
41 | pref.enable_detached_surface_texture
42 |
43 |
44 |
45 | Player: None
46 | Player: AndroidMediaPlayer
47 | Player: IjkMediaPlayer
48 | Player: IjkExoMediaPlayer
49 | Media Information
50 | Player
51 | Media
52 | Profile level
53 | Pixel format
54 | Resolution
55 | Length
56 | Stream #%d
57 | Type
58 | Language
59 | Codec
60 | Frame rate
61 | Bit rate
62 | Sample rate
63 | Channels
64 | *
65 | *
66 |
67 | Video
68 | Audio
69 | Subtitle
70 | Timed text
71 | Meta data
72 | Unknown
73 |
74 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/java/js/nch/videoplay/video/TableLayoutBinder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Zhang Rui
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package js.nch.videoplay.video;
18 |
19 | import android.content.Context;
20 | import android.support.v7.app.AlertDialog;
21 | import android.view.LayoutInflater;
22 | import android.view.View;
23 | import android.view.ViewGroup;
24 | import android.widget.TableLayout;
25 | import android.widget.TextView;
26 |
27 | import js.nch.videoplay.R;
28 |
29 |
30 | public class TableLayoutBinder {
31 | private Context mContext;
32 | public ViewGroup mTableView;
33 | public TableLayout mTableLayout;
34 |
35 | public TableLayoutBinder(Context context) {
36 | this(context, R.layout.table_media_info);
37 | }
38 |
39 | public TableLayoutBinder(Context context, int layoutResourceId) {
40 | mContext = context;
41 | mTableView = (ViewGroup) LayoutInflater.from(mContext).inflate(layoutResourceId, null);
42 | mTableLayout = (TableLayout) mTableView.findViewById(R.id.table);
43 | }
44 |
45 | public TableLayoutBinder(Context context, TableLayout tableLayout) {
46 | mContext = context;
47 | mTableView = tableLayout;
48 | mTableLayout = tableLayout;
49 | }
50 |
51 | public View appendRow1(String name, String value) {
52 | return appendRow(R.layout.table_media_info_row1, name, value);
53 | }
54 |
55 | public View appendRow1(int nameId, String value) {
56 | return appendRow1(mContext.getString(nameId), value);
57 | }
58 |
59 | public View appendRow2(String name, String value) {
60 | return appendRow(R.layout.table_media_info_row2, name, value);
61 | }
62 |
63 | public View appendRow2(int nameId, String value) {
64 | return appendRow2(mContext.getString(nameId), value);
65 | }
66 |
67 | public View appendSection(String name) {
68 | return appendRow(R.layout.table_media_info_section, name, null);
69 | }
70 |
71 | public View appendSection(int nameId) {
72 | return appendSection(mContext.getString(nameId));
73 | }
74 |
75 | public View appendRow(int layoutId, String name, String value) {
76 | ViewGroup rowView = (ViewGroup) LayoutInflater.from(mContext).inflate(layoutId, mTableLayout, false);
77 | setNameValueText(rowView, name, value);
78 |
79 | mTableLayout.addView(rowView);
80 | return rowView;
81 | }
82 |
83 | public ViewHolder obtainViewHolder(View rowView) {
84 | ViewHolder viewHolder = (ViewHolder) rowView.getTag();
85 | if (viewHolder == null) {
86 | viewHolder = new ViewHolder();
87 | viewHolder.mNameTextView = (TextView) rowView.findViewById(R.id.name);
88 | viewHolder.mValueTextView = (TextView) rowView.findViewById(R.id.value);
89 | rowView.setTag(viewHolder);
90 | }
91 | return viewHolder;
92 | }
93 |
94 | public void setNameValueText(View rowView, String name, String value) {
95 | ViewHolder viewHolder = obtainViewHolder(rowView);
96 | viewHolder.setName(name);
97 | viewHolder.setValue(value);
98 | }
99 |
100 | public void setValueText(View rowView, String value) {
101 | ViewHolder viewHolder = obtainViewHolder(rowView);
102 | viewHolder.setValue(value);
103 | }
104 |
105 | public ViewGroup buildLayout() {
106 | return mTableView;
107 | }
108 |
109 | public AlertDialog.Builder buildAlertDialogBuilder() {
110 | AlertDialog.Builder dlgBuilder = new AlertDialog.Builder(mContext);
111 | dlgBuilder.setView(buildLayout());
112 | return dlgBuilder;
113 | }
114 |
115 | private static class ViewHolder {
116 | public TextView mNameTextView;
117 | public TextView mValueTextView;
118 |
119 | public void setName(String name) {
120 | if (mNameTextView != null) {
121 | mNameTextView.setText(name);
122 | }
123 | }
124 |
125 | public void setValue(String value) {
126 | if (mValueTextView != null) {
127 | mValueTextView.setText(value);
128 | }
129 | }
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/java/js/nch/videoplay/video/Settings.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Zhang Rui
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package js.nch.videoplay.video;
18 |
19 | import android.content.Context;
20 | import android.content.SharedPreferences;
21 | import android.preference.PreferenceManager;
22 |
23 | import js.nch.videoplay.R;
24 |
25 |
26 | public class Settings {
27 | private Context mAppContext;
28 | private SharedPreferences mSharedPreferences;
29 |
30 | public static final int PV_PLAYER__Auto = 0;
31 | public static final int PV_PLAYER__AndroidMediaPlayer = 1;
32 | public static final int PV_PLAYER__IjkMediaPlayer = 2;
33 | public static final int PV_PLAYER__IjkExoMediaPlayer = 3;
34 |
35 | public Settings(Context context) {
36 | mAppContext = context.getApplicationContext();
37 | mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(mAppContext);
38 | }
39 |
40 | public boolean getEnableBackgroundPlay() {
41 | String key = mAppContext.getString(R.string.pref_key_enable_background_play);
42 | return mSharedPreferences.getBoolean(key, false);
43 | }
44 |
45 | public int getPlayer() {
46 | String key = mAppContext.getString(R.string.pref_key_player);
47 | String value = mSharedPreferences.getString(key, "");
48 | try {
49 | return Integer.valueOf(value).intValue();
50 | } catch (NumberFormatException e) {
51 | return 0;
52 | }
53 | }
54 |
55 | public boolean getUsingMediaCodec() {
56 | String key = mAppContext.getString(R.string.pref_key_using_media_codec);
57 | return mSharedPreferences.getBoolean(key, false);
58 | }
59 |
60 | public boolean getUsingMediaCodecAutoRotate() {
61 | String key = mAppContext.getString(R.string.pref_key_using_media_codec_auto_rotate);
62 | return mSharedPreferences.getBoolean(key, false);
63 | }
64 |
65 | public boolean getUsingOpenSLES() {
66 | String key = mAppContext.getString(R.string.pref_key_using_opensl_es);
67 | return mSharedPreferences.getBoolean(key, false);
68 | }
69 |
70 | public String getPixelFormat() {
71 | String key = mAppContext.getString(R.string.pref_key_pixel_format);
72 | return mSharedPreferences.getString(key, "");
73 | }
74 |
75 | public boolean getEnableNoView() {
76 | String key = mAppContext.getString(R.string.pref_key_enable_no_view);
77 | return mSharedPreferences.getBoolean(key, false);
78 | }
79 |
80 | public boolean getEnableSurfaceView() {
81 | String key = mAppContext.getString(R.string.pref_key_enable_surface_view);
82 | return mSharedPreferences.getBoolean(key, false);
83 | }
84 |
85 | public boolean getEnableTextureView() {
86 | String key = mAppContext.getString(R.string.pref_key_enable_texture_view);
87 | return mSharedPreferences.getBoolean(key, false);
88 | }
89 |
90 | public boolean getEnableDetachedSurfaceTextureView() {
91 | String key = mAppContext.getString(R.string.pref_key_enable_detached_surface_texture);
92 | return mSharedPreferences.getBoolean(key, false);
93 | }
94 |
95 | public String getLastDirectory() {
96 | String key = mAppContext.getString(R.string.pref_key_last_directory);
97 | return mSharedPreferences.getString(key, "/");
98 | }
99 |
100 | public void setLastDirectory(String path) {
101 | String key = mAppContext.getString(R.string.pref_key_last_directory);
102 | mSharedPreferences.edit().putString(key, path).apply();
103 | }
104 |
105 | public void setEnableTextureView(boolean enable){
106 | String key = mAppContext.getString(R.string.pref_key_enable_texture_view);
107 | SharedPreferences.Editor editor=mSharedPreferences.edit();
108 | editor.putBoolean(key,enable);
109 | editor.commit();
110 | }
111 |
112 | public void setEnableSurfaceView(boolean enable){
113 | String key = mAppContext.getString(R.string.pref_key_enable_surface_view);
114 | SharedPreferences.Editor editor=mSharedPreferences.edit();
115 | editor.putBoolean(key,enable);
116 | editor.commit();
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/app/src/main/java/js/listvideodemo/viewpager/ViewPagerActivity.java:
--------------------------------------------------------------------------------
1 | package js.listvideodemo.viewpager;
2 |
3 | import android.content.res.Configuration;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.design.widget.TabLayout;
7 | import android.support.v4.view.ViewPager;
8 | import android.support.v7.app.AppCompatActivity;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.RelativeLayout;
12 |
13 | import java.util.ArrayList;
14 |
15 | import js.listvideodemo.R;
16 | import js.nch.videoplay.FullScreenTouch;
17 | import js.nch.videoplay.VideoPlayView;
18 | import js.nch.videoplay.VideoPlayViewManage;
19 | import tv.danmaku.ijk.media.player.IMediaPlayer;
20 |
21 | /**
22 | * Created by peter on 16/8/31.
23 | */
24 | public class ViewPagerActivity extends AppCompatActivity {
25 |
26 | private TabLayout tabs;
27 | private ViewPager vpVideo;
28 | private ArrayList data = new ArrayList<>();
29 | private RelativeLayout fullScreen;
30 | private VideoPlayView videoPlayView;
31 |
32 | @Override
33 | protected void onCreate(@Nullable Bundle savedInstanceState) {
34 | super.onCreate(savedInstanceState);
35 | setContentView(R.layout.activity_viewpager);
36 |
37 | tabs = (TabLayout) findViewById(R.id.tabs);
38 | tabs.setTabMode(TabLayout.MODE_SCROLLABLE);
39 | fullScreen = (RelativeLayout) findViewById(R.id.full_screen);
40 | videoPlayView = VideoPlayViewManage.getManage().initialize(this);
41 |
42 | vpVideo = (ViewPager) findViewById(R.id.vp_video);
43 | data.add("one");
44 | data.add("two");
45 | data.add("three");
46 |
47 | VideoFramentAdapter adapter = new VideoFramentAdapter(ViewPagerActivity.this,getSupportFragmentManager(), data,videoPlayView);
48 | vpVideo.setAdapter(adapter);
49 | tabs.setupWithViewPager(vpVideo);
50 | tabs.setTabsFromPagerAdapter(adapter);
51 |
52 |
53 | fullScreen.setOnTouchListener(new FullScreenTouch(this, true));
54 |
55 | //播放完还原播放界面
56 | videoPlayView.setCompletionListener(new VideoPlayView.CompletionListener() {
57 | @Override
58 | public void completion(IMediaPlayer mp) {
59 |
60 | videoPlayView.release();
61 | ViewGroup last = (ViewGroup) videoPlayView.getParent();//找到videoitemview的父类,然后remove
62 | if (last != null && last.getChildCount() > 0) {
63 | last.removeAllViews();
64 | View itemView = (View) last.getParent();
65 | if (itemView != null) {
66 | itemView.findViewById(R.id.showview).setVisibility(View.VISIBLE);
67 | }
68 | }
69 | }
70 | });
71 |
72 | }
73 | //点击播放视频的回调
74 | private ConfigurationChanged onConfigurationChanged;
75 | public void setonConfigurationChanged(ConfigurationChanged onConfigurationChanged){
76 | this.onConfigurationChanged=onConfigurationChanged;
77 | }
78 | public interface ConfigurationChanged{
79 | void Changed();
80 | }
81 | @Override
82 | public void onConfigurationChanged(Configuration newConfig) {
83 | super.onConfigurationChanged(newConfig);
84 | if (videoPlayView != null) {
85 | videoPlayView.onChanged(newConfig);
86 | if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
87 | fullScreen.setVisibility(View.GONE);
88 | fullScreen.removeAllViews();
89 | if (null!=onConfigurationChanged){
90 | onConfigurationChanged.Changed();
91 | }
92 |
93 | videoPlayView.setContorllerVisiable();
94 | int mShowFlags =
95 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
96 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
97 | | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
98 | fullScreen.setSystemUiVisibility(mShowFlags);
99 | } else {
100 |
101 | ViewGroup viewGroup = (ViewGroup) videoPlayView.getParent();
102 | if (viewGroup == null)
103 | return;
104 | viewGroup.removeAllViews();
105 | fullScreen.addView(videoPlayView);
106 | fullScreen.setVisibility(View.VISIBLE);
107 |
108 | int mHideFlags =
109 | View.SYSTEM_UI_FLAG_LOW_PROFILE
110 | | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
111 | | View.SYSTEM_UI_FLAG_FULLSCREEN
112 | | View.SYSTEM_UI_FLAG_IMMERSIVE
113 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
114 | | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
115 | ;
116 | fullScreen.setSystemUiVisibility(mHideFlags);
117 | }
118 | } else {
119 | fullScreen.setVisibility(View.GONE);
120 | }
121 | }
122 |
123 | @Override
124 | protected void onPause() {
125 | super.onPause();
126 | videoPlayView.stopPlayVideo();
127 | }
128 |
129 | }
130 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/layout/media_contoller.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
16 |
17 |
18 |
28 |
29 |
35 |
36 |
40 |
41 |
42 |
48 |
49 |
56 |
57 |
62 |
63 |
70 |
71 |
80 |
81 |
94 |
95 |
102 |
103 |
109 |
110 |
115 |
116 |
117 |
118 |
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/java/js/nch/videoplay/video/InfoHudViewHolder.java:
--------------------------------------------------------------------------------
1 | package js.nch.videoplay.video;
2 |
3 | import android.content.Context;
4 | import android.os.Handler;
5 | import android.os.Message;
6 | import android.util.SparseArray;
7 | import android.view.View;
8 | import android.widget.TableLayout;
9 |
10 | import java.util.Locale;
11 |
12 | import js.nch.videoplay.R;
13 | import tv.danmaku.ijk.media.player.IMediaPlayer;
14 | import tv.danmaku.ijk.media.player.IjkMediaPlayer;
15 | import tv.danmaku.ijk.media.player.MediaPlayerProxy;
16 |
17 | public class InfoHudViewHolder {
18 | private TableLayoutBinder mTableLayoutBinder;
19 | private SparseArray mRowMap = new SparseArray();
20 | private IMediaPlayer mMediaPlayer;
21 |
22 | public InfoHudViewHolder(Context context, TableLayout tableLayout) {
23 | mTableLayoutBinder = new TableLayoutBinder(context, tableLayout);
24 | }
25 |
26 | private void appendSection(int nameId) {
27 | mTableLayoutBinder.appendSection(nameId);
28 | }
29 |
30 | private void appendRow(int nameId) {
31 | View rowView = mTableLayoutBinder.appendRow2(nameId, null);
32 | mRowMap.put(nameId, rowView);
33 | }
34 |
35 | private void setRowValue(int id, String value) {
36 | View rowView = mRowMap.get(id);
37 | if (rowView == null) {
38 | rowView = mTableLayoutBinder.appendRow2(id, value);
39 | mRowMap.put(id, rowView);
40 | } else {
41 | mTableLayoutBinder.setValueText(rowView, value);
42 | }
43 | }
44 |
45 | public void setMediaPlayer(IMediaPlayer mp) {
46 | mMediaPlayer = mp;
47 | if (mMediaPlayer != null) {
48 | mHandler.sendEmptyMessageDelayed(MSG_UPDATE_HUD, 500);
49 | } else {
50 | mHandler.removeMessages(MSG_UPDATE_HUD);
51 | }
52 | }
53 |
54 | private static String formatedDurationMilli(long duration) {
55 | if (duration >= 1000) {
56 | return String.format(Locale.US, "%.2f sec", ((float)duration) / 1000);
57 | } else {
58 | return String.format(Locale.US, "%d msec", duration);
59 | }
60 | }
61 |
62 | private static String formatedSize(long bytes) {
63 | if (bytes >= 100 * 1000) {
64 | return String.format(Locale.US, "%.2f MB", ((float)bytes) / 1000 / 1000);
65 | } else if (bytes >= 100) {
66 | return String.format(Locale.US, "%.1f KB", ((float)bytes) / 1000);
67 | } else {
68 | return String.format(Locale.US, "%d B", bytes);
69 | }
70 | }
71 |
72 | private static final int MSG_UPDATE_HUD = 1;
73 | private Handler mHandler = new Handler() {
74 | @Override
75 | public void handleMessage(Message msg) {
76 | switch (msg.what) {
77 | case MSG_UPDATE_HUD: {
78 | InfoHudViewHolder holder = InfoHudViewHolder.this;
79 | IjkMediaPlayer mp = null;
80 | if (mMediaPlayer == null)
81 | break;
82 | if (mMediaPlayer instanceof IjkMediaPlayer) {
83 | mp = (IjkMediaPlayer) mMediaPlayer;
84 | } else if (mMediaPlayer instanceof MediaPlayerProxy) {
85 | MediaPlayerProxy proxy = (MediaPlayerProxy) mMediaPlayer;
86 | IMediaPlayer internal = proxy.getInternalMediaPlayer();
87 | if (internal != null && internal instanceof IjkMediaPlayer)
88 | mp = (IjkMediaPlayer) internal;
89 | }
90 | if (mp == null)
91 | break;
92 |
93 | int vdec = mp.getVideoDecoder();
94 | switch (vdec) {
95 | case IjkMediaPlayer.FFP_PROPV_DECODER_AVCODEC:
96 | setRowValue(R.string.vdec, "avcodec");
97 | break;
98 | case IjkMediaPlayer.FFP_PROPV_DECODER_MEDIACODEC:
99 | setRowValue(R.string.vdec, "MediaCodec");
100 | break;
101 | default:
102 | setRowValue(R.string.vdec, "");
103 | break;
104 | }
105 |
106 | float fpsOutput = mp.getVideoOutputFramesPerSecond();
107 | float fpsDecode = mp.getVideoDecodeFramesPerSecond();
108 | setRowValue(R.string.fps, String.format(Locale.US, "%.2f / %.2f", fpsDecode, fpsOutput));
109 |
110 | long videoCachedDuration = mp.getVideoCachedDuration();
111 | long audioCachedDuration = mp.getAudioCachedDuration();
112 | long videoCachedBytes = mp.getVideoCachedBytes();
113 | long audioCachedBytes = mp.getAudioCachedBytes();
114 |
115 | setRowValue(R.string.v_cache, String.format(Locale.US, "%s, %s", formatedDurationMilli(videoCachedDuration), formatedSize(videoCachedBytes)));
116 | setRowValue(R.string.a_cache, String.format(Locale.US, "%s, %s", formatedDurationMilli(audioCachedDuration), formatedSize(audioCachedBytes)));
117 |
118 | mHandler.removeMessages(MSG_UPDATE_HUD);
119 | mHandler.sendEmptyMessageDelayed(MSG_UPDATE_HUD, 500);
120 | }
121 | }
122 | }
123 | };
124 | }
125 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/app/src/main/java/js/listvideodemo/list/ListVideoAdapter.java:
--------------------------------------------------------------------------------
1 | package js.listvideodemo.list;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.ImageView;
8 | import android.widget.RelativeLayout;
9 | import android.widget.TextView;
10 |
11 | import com.nostra13.universalimageloader.core.ImageLoader;
12 |
13 | import java.util.ArrayList;
14 |
15 | import js.listvideodemo.ImageLoaderOptions;
16 | import js.listvideodemo.R;
17 | import js.listvideodemo.Utils;
18 |
19 | /**
20 | * Created by peter on 16/8/31.
21 | */
22 | public class ListVideoAdapter extends RecyclerView.Adapter {
23 | private final Context mContext;
24 | private ArrayList dataListImage = new ArrayList<>();
25 | private ArrayList dataListTitle = new ArrayList<>();
26 | private ArrayList dataListName = new ArrayList<>();
27 |
28 | public ListVideoAdapter(Context context){
29 | this.mContext = context;
30 | dataListImage.add("http://p1.qiaonaoke.com/image/2016/0703/23/30ef1d22ee3deb70.jpg");
31 | dataListImage.add("http://p1.qiaonaoke.com/image/2016/0703/23/30ef1d22ee3deb70.jpg");
32 | dataListImage.add("http://p1.qiaonaoke.com/image/2016/0703/23/30ef1d22ee3deb70.jpg");
33 | dataListImage.add("http://p1.qiaonaoke.com/image/2016/0703/23/30ef1d22ee3deb70.jpg");
34 | dataListImage.add("http://p1.qiaonaoke.com/image/2016/0703/23/30ef1d22ee3deb70.jpg");
35 | dataListTitle.add("Context");
36 | dataListTitle.add("Context");
37 | dataListTitle.add("Context");
38 | dataListTitle.add("Context");
39 | dataListTitle.add("Context");
40 | dataListName.add("dataListName");
41 | dataListName.add("dataListName");
42 | dataListName.add("dataListName");
43 | dataListName.add("dataListName");
44 | dataListName.add("dataListName");
45 | }
46 | @Override
47 | public ListVideoAdapter.VideoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
48 | View view = View.inflate(mContext, R.layout.item_video, null);
49 | VideoViewHolder holder = new VideoViewHolder(view);
50 | view.setTag(holder);
51 | return new VideoViewHolder(view);
52 | }
53 |
54 | @Override
55 | public void onBindViewHolder(ListVideoAdapter.VideoViewHolder holder, int position) {
56 | holder.update(position);
57 | }
58 |
59 | @Override
60 | public int getItemCount() {
61 | return dataListName.size();
62 | }
63 | public class VideoViewHolder extends RecyclerView.ViewHolder {
64 | private TextView time; //时间
65 | private ImageView image; //视频图片
66 | private ImageView ivVideoHead;//发布视频的头像
67 | private TextView tvVideoName;//发布视频的名称
68 | private TextView tvVideoWatchCount;//播放次数
69 | private RelativeLayout layout;
70 | private ImageView ivVideoShare;//分享图标
71 | private ImageView ivVideoMore;//更多图标
72 | private RelativeLayout rlVideoMore;
73 | public RelativeLayout showView;//播放视频控件
74 | private TextView title;//名称
75 |
76 | public VideoViewHolder(View itemView) {
77 | super(itemView);
78 |
79 | showView= (RelativeLayout) itemView.findViewById(R.id.showview);
80 | rlVideoMore = (RelativeLayout) itemView.findViewById(R.id.rl_video_more);
81 | layout = (RelativeLayout) itemView.findViewById(R.id.layout);
82 | title= (TextView) itemView.findViewById(R.id.title);
83 | time = (TextView) itemView.findViewById(R.id.time);
84 | tvVideoName = (TextView) itemView.findViewById(R.id.tv_video_name);
85 | tvVideoWatchCount = (TextView) itemView.findViewById(R.id.tv_video_watch_count);
86 | image = (ImageView) itemView.findViewById(R.id.image_bg);
87 | ivVideoHead = (ImageView) itemView.findViewById(R.id.iv_video_head);
88 | ivVideoShare = (ImageView) itemView.findViewById(R.id.iv_video_share);
89 | ivVideoMore = (ImageView) itemView.findViewById(R.id.iv_video_more);
90 | if (layout!=null){
91 | RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) layout.getLayoutParams();
92 | layoutParams.height = Utils.getVideoHeight();
93 | layout.setLayoutParams(layoutParams);
94 | }
95 | }
96 |
97 | public void update(final int position) {
98 | //分享点击
99 | ivVideoShare.setOnClickListener(new View.OnClickListener() {
100 | @Override
101 | public void onClick(View v) {
102 | }
103 | });
104 | //更多点击
105 | rlVideoMore.setOnClickListener(new View.OnClickListener() {
106 | @Override
107 | public void onClick(View v) {
108 | }
109 | });
110 | //更多点击
111 | ivVideoMore.setOnClickListener(new View.OnClickListener() {
112 | @Override
113 | public void onClick(View v) {
114 |
115 | }
116 | });
117 | //视频图片
118 | ImageLoader.getInstance().displayImage(dataListImage.get(position),
119 | image, ImageLoaderOptions.list_options);
120 | //发布者头像
121 | ImageLoader.getInstance().displayImage(dataListImage.get(position),
122 | ivVideoHead, ImageLoaderOptions.list_options);
123 | //标题
124 | title.setText(dataListTitle.get(position));
125 | //时长
126 | time.setText(dataListTitle.get(position));
127 | //发布者的名字
128 | tvVideoName.setText(dataListName.get(position));
129 | //播放次数
130 | tvVideoWatchCount.setText(dataListName.get(position));
131 | //点击回调 播放视频
132 | showView.setOnClickListener(new View.OnClickListener() {
133 | @Override
134 | public void onClick(View v) {
135 | if (playclick != null)
136 | playclick.onPlayclick(position, showView);
137 | }
138 | });
139 | }
140 | }
141 |
142 | private onPlayClick playclick;
143 | public void setPlayClick(onPlayClick playclick){
144 | this.playclick=playclick;
145 | }
146 | public interface onPlayClick{
147 | void onPlayclick(int position,RelativeLayout image);
148 | }
149 |
150 | }
151 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/res/layout/item_video.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
12 |
13 |
17 |
18 |
19 |
20 |
24 |
25 |
30 |
31 |
37 |
38 |
48 |
49 |
64 |
65 |
66 |
67 |
68 |
75 |
76 |
82 |
83 |
88 |
89 |
97 |
98 |
102 |
103 |
111 |
112 |
118 |
119 |
125 |
126 |
132 |
133 |
134 |
135 |
136 |
140 |
141 |
142 |
143 |
149 |
150 |
159 |
160 |
168 |
169 |
170 |
--------------------------------------------------------------------------------
/app/src/main/java/js/listvideodemo/viewpager/ListVideoFrament.java:
--------------------------------------------------------------------------------
1 | package js.listvideodemo.viewpager;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v4.app.Fragment;
6 | import android.support.v7.widget.LinearLayoutManager;
7 | import android.support.v7.widget.RecyclerView;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.FrameLayout;
12 | import android.widget.RelativeLayout;
13 |
14 | import js.listvideodemo.R;
15 | import js.listvideodemo.list.ListVideoAdapter;
16 | import js.nch.videoplay.VideoPlayView;
17 | import js.nch.videoplay.video.IjkVideoView;
18 |
19 | /**
20 | * Created by peter on 16/8/31.
21 | */
22 | public class ListVideoFrament extends Fragment {
23 |
24 | private ViewPagerActivity viewPagerActivity;
25 | private VideoPlayView videoPlayView;
26 | private RecyclerView recyclerView;
27 | private ListVideoAdapter listVideoAdapter;
28 | private LinearLayoutManager mLayoutManager;
29 | private int postion = -1;
30 | private int lastPostion = -1;
31 | private View view;
32 | private String video_url;
33 |
34 | public ListVideoFrament(ViewPagerActivity viewPagerActivity, VideoPlayView videoPlayView) {
35 | this.videoPlayView = videoPlayView;
36 | this.viewPagerActivity = viewPagerActivity;
37 | }
38 |
39 | @Nullable
40 | @Override
41 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
42 | view = View.inflate(getActivity(), R.layout.frament_list, null);
43 | initUI();
44 | initVideoPlay();
45 | return view;
46 | }
47 |
48 | private void initUI() {
49 | recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
50 | mLayoutManager = new LinearLayoutManager(getActivity());
51 | listVideoAdapter = new ListVideoAdapter(getActivity());
52 | recyclerView.setAdapter(listVideoAdapter);
53 | recyclerView.setLayoutManager(mLayoutManager);
54 | }
55 |
56 | private void initVideoPlay() {
57 |
58 |
59 |
60 | listVideoAdapter.setPlayClick(new ListVideoAdapter.onPlayClick() {
61 | @Override
62 | public void onPlayclick(int position, RelativeLayout image) {
63 | image.setVisibility(View.GONE);
64 | if (videoPlayView.isPlay() && lastPostion == position) {
65 | return;
66 | }
67 | postion = position;
68 | if (videoPlayView.VideoStatus() == IjkVideoView.STATE_PAUSED) {
69 |
70 | if (position != lastPostion) {
71 | videoPlayView.stopPlayVideo();
72 | videoPlayView.release();
73 | }
74 | }
75 | if (lastPostion != -1) {
76 | videoPlayView.setShowContoller(true);
77 | videoPlayView.showView();
78 | }
79 |
80 | View view = recyclerView.findViewHolderForAdapterPosition(position).itemView;
81 | FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.layout_video);
82 | frameLayout.removeAllViews();
83 |
84 | videoPlayView.showView();
85 | frameLayout.addView(videoPlayView);
86 | video_url = "http://106.38.75.98:8092/video/2016/0901/12/b4fcb03e407bdc39.mp4";
87 | videoPlayView.start(video_url, "title");
88 | lastPostion = position;
89 | }
90 | });
91 |
92 | //显示||关闭 小窗口
93 | recyclerView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {
94 | @Override
95 | public void onChildViewAttachedToWindow(View view) {
96 | int index = recyclerView.getChildAdapterPosition(view);
97 | view.findViewById(R.id.showview).setVisibility(View.VISIBLE);
98 | if (index == postion) {
99 |
100 | FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.layout_video);
101 | frameLayout.removeAllViews();
102 | if (videoPlayView != null &&
103 | ((videoPlayView.isPlay()) || videoPlayView.VideoStatus() == IjkVideoView.STATE_PAUSED)) {
104 | view.findViewById(R.id.showview).setVisibility(View.GONE);
105 | }
106 |
107 | if (videoPlayView.VideoStatus() == IjkVideoView.STATE_PAUSED) {
108 | if (videoPlayView.getParent() != null)
109 | ((ViewGroup) videoPlayView.getParent()).removeAllViews();
110 | frameLayout.addView(videoPlayView);
111 | return;
112 | }
113 | }
114 | }
115 |
116 | @Override
117 | public void onChildViewDetachedFromWindow(View view) {
118 | int index = recyclerView.getChildAdapterPosition(view);
119 | if (index == postion) {
120 | //是否删除小屏
121 | if (true) {
122 | if (videoPlayView != null) {
123 | videoPlayView.stop();
124 | videoPlayView.release();
125 | }
126 | }
127 | }
128 | }
129 | });
130 | }
131 | @Override
132 | public void setUserVisibleHint(boolean isVisibleToUser) {
133 | if (isVisibleToUser){
134 | viewPagerActivity.setonConfigurationChanged(new ViewPagerActivity.ConfigurationChanged() {
135 | @Override
136 | public void Changed() {
137 | if (postion <= mLayoutManager.findLastVisibleItemPosition()
138 | && postion >= mLayoutManager.findFirstVisibleItemPosition()) {
139 |
140 | View view = recyclerView.findViewHolderForAdapterPosition(postion).itemView;
141 | FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.layout_video);
142 | frameLayout.removeAllViews();
143 | ViewGroup last = (ViewGroup) videoPlayView.getParent();//找到videoitemview的父类,然后remove
144 | if (last != null) {
145 | last.removeAllViews();
146 | }
147 | frameLayout.addView(videoPlayView);
148 | videoPlayView.setShowContoller(true);
149 | } else {
150 | videoPlayView.setShowContoller(true);
151 | }
152 | }
153 | });
154 | }else {
155 | videoPlayView.stopVideo();
156 | }
157 | }
158 |
159 |
160 | }
161 |
--------------------------------------------------------------------------------
/app/src/main/java/js/listvideodemo/playpage/PlayPageActivity.java:
--------------------------------------------------------------------------------
1 | package js.listvideodemo.playpage;
2 |
3 | import android.content.res.Configuration;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.view.WindowManager;
10 | import android.widget.FrameLayout;
11 | import android.widget.ImageView;
12 | import android.widget.LinearLayout;
13 | import android.widget.RelativeLayout;
14 | import android.widget.TextView;
15 |
16 | import com.nostra13.universalimageloader.core.ImageLoader;
17 |
18 | import js.listvideodemo.ImageLoaderOptions;
19 | import js.listvideodemo.R;
20 | import js.listvideodemo.Utils;
21 | import js.nch.videoplay.FullScreenTouch;
22 | import js.nch.videoplay.VideoPlayView;
23 | import js.nch.videoplay.VideoPlayViewManage;
24 | import tv.danmaku.ijk.media.player.IMediaPlayer;
25 |
26 | /**
27 | * Created by peter on 16/9/1.
28 | */
29 | public class PlayPageActivity extends AppCompatActivity{
30 |
31 | private VideoPlayView videoPlayView;
32 | private LinearLayout llContent;
33 | private RelativeLayout showView;
34 | private FrameLayout layoutVideo;
35 | private ImageView ivVideoImg;
36 | private ImageView ivVideoPlay;
37 | private RelativeLayout rlBack;
38 | private RelativeLayout fullScreen;
39 | private TextView textView;
40 |
41 | @Override
42 | protected void onCreate(@Nullable Bundle savedInstanceState) {
43 | super.onCreate(savedInstanceState);
44 | setContentView(R.layout.activity_play);
45 |
46 | videoPlayView = VideoPlayViewManage.getManage().initialize(this);
47 |
48 | initUI();
49 |
50 | initVideoPlay();
51 | }
52 |
53 | private void initVideoPlay() {
54 | ivVideoImg.setOnClickListener(new View.OnClickListener() {
55 | @Override
56 | public void onClick(View v) {
57 | ivVideoImg.setVisibility(View.GONE);
58 | ivVideoPlay.setVisibility(View.GONE);
59 | ViewGroup last = (ViewGroup) videoPlayView.getParent();
60 | if (last != null) {
61 | last.removeAllViews();
62 | }
63 | videoPlayView.showView();
64 | layoutVideo.removeAllViews();
65 | videoPlayView.showView();
66 | layoutVideo.addView(videoPlayView);
67 | videoPlayView.setContorllerVisiable();
68 | videoPlayView.start("http://106.38.75.98:8092/video/2016/0901/12/b4fcb03e407bdc39.mp4", "title");
69 |
70 | }
71 | });
72 | //播放完还原播放界面
73 | videoPlayView.setCompletionListener(new VideoPlayView.CompletionListener() {
74 | @Override
75 | public void completion(IMediaPlayer mp) {
76 |
77 | videoPlayView.release();
78 | ViewGroup last = (ViewGroup) videoPlayView.getParent();//找到videoitemview的父类,然后remove
79 | if (last != null) {
80 | last.removeAllViews();
81 | }
82 | ivVideoImg.setVisibility(View.VISIBLE);
83 | ivVideoPlay.setVisibility(View.VISIBLE);
84 | ImageLoader.getInstance().displayImage("http://p1.qiaonaoke.com/image/2016/0703/23/30ef1d22ee3deb70.jpg",
85 | ivVideoImg, ImageLoaderOptions.list_options);
86 |
87 | }
88 | });
89 | rlBack.setOnClickListener(new View.OnClickListener() {
90 | @Override
91 | public void onClick(View v) {
92 | finish();
93 | }
94 | });
95 | fullScreen.setOnTouchListener(new FullScreenTouch(this, true));
96 | //找到videoitemview的父类,然后remove
97 | ViewGroup last = (ViewGroup) videoPlayView.getParent();
98 | if (last != null) {
99 | last.removeAllViews();
100 | }
101 | videoPlayView.showView();
102 | layoutVideo.removeAllViews();
103 | videoPlayView.showView();
104 | layoutVideo.addView(videoPlayView);
105 | videoPlayView.setContorllerVisiable();
106 | videoPlayView.videoPlayController.setBackIcon();
107 | }
108 |
109 | private void initUI() {
110 |
111 | llContent = (LinearLayout) findViewById(R.id.ll_content);
112 | showView = (RelativeLayout) findViewById(R.id.showview);
113 | layoutVideo = (FrameLayout) findViewById(R.id.layout_video);
114 | ivVideoImg = (ImageView) findViewById(R.id.iv_video_img);
115 | ivVideoPlay = (ImageView) findViewById(R.id.iv_video_play);
116 | rlBack = (RelativeLayout) findViewById(R.id.rl_back);
117 | fullScreen = (RelativeLayout) findViewById(R.id.full_screen);
118 |
119 | LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) showView.getLayoutParams();
120 | layoutParams.height = Utils.getVideoHeight();
121 | showView.setLayoutParams(layoutParams);
122 | textView = new TextView(this);
123 | textView.setText("我的视频播放页的内容");
124 | textView.setTextSize(35);
125 | llContent.addView(textView);
126 |
127 | }
128 | @Override
129 | public void onConfigurationChanged(Configuration newConfig) {
130 | super.onConfigurationChanged(newConfig);
131 | if (videoPlayView != null) {
132 | videoPlayView.onChanged(newConfig);
133 | if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
134 | //小屏播放的UI处理
135 | fullScreen.setVisibility(View.GONE);
136 | textView.setVisibility(View.VISIBLE);
137 | fullScreen.removeAllViews();
138 | layoutVideo.removeAllViews();
139 | layoutVideo.addView(videoPlayView);
140 | videoPlayView.setShowContoller(true);
141 | //如果有虚拟控件 显示虚拟控件 没有的虚拟控件则无效
142 | int mShowFlags =
143 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
144 | | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
145 | fullScreen.setSystemUiVisibility(mShowFlags);
146 | WindowManager.LayoutParams lp = getWindow().getAttributes();
147 | lp.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
148 | getWindow().setAttributes(lp);
149 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
150 |
151 | } else {
152 | //全屏播放的UI处理
153 | ViewGroup viewGroup = (ViewGroup) videoPlayView.getParent();
154 | if (viewGroup == null)
155 | return;
156 | viewGroup.removeAllViews();
157 | fullScreen.addView(videoPlayView);
158 | fullScreen.setVisibility(View.VISIBLE);
159 | textView.setVisibility(View.GONE);
160 | //如果有虚拟控件 隐藏虚拟控件 没有的虚拟控件则无效
161 | int mHideFlags = View.SYSTEM_UI_FLAG_LOW_PROFILE
162 | | View.SYSTEM_UI_FLAG_IMMERSIVE
163 | | View.SYSTEM_UI_FLAG_FULLSCREEN
164 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
165 | | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
166 | fullScreen.setSystemUiVisibility(mHideFlags);
167 | }
168 | } else {
169 | fullScreen.setVisibility(View.GONE);
170 | }
171 | videoPlayView.videoPlayController.setBackIcon();
172 | }
173 |
174 | @Override
175 | protected void onDestroy() {
176 | super.onDestroy();
177 | videoPlayView.pause();
178 | }
179 |
180 | @Override
181 | protected void onPause() {
182 | super.onPause();
183 | videoPlayView.pause();
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/ListVideoPlay/ListVideoPlay.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | generateDebugAndroidTestSources
19 | generateDebugSources
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 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/java/js/nch/videoplay/VideoPlayView.java:
--------------------------------------------------------------------------------
1 | package js.nch.videoplay;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.pm.ActivityInfo;
6 | import android.content.res.Configuration;
7 | import android.media.MediaPlayer;
8 | import android.net.Uri;
9 | import android.os.Handler;
10 | import android.view.LayoutInflater;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 | import android.view.WindowManager;
14 | import android.widget.RelativeLayout;
15 |
16 | import js.nch.videoplay.video.IjkVideoView;
17 | import tv.danmaku.ijk.media.player.IMediaPlayer;
18 | /**
19 | * Description 播放view
20 | */
21 | public class VideoPlayView extends RelativeLayout implements MediaPlayer.OnInfoListener, MediaPlayer.OnBufferingUpdateListener {
22 |
23 | private String TAG = "VideoPlayView :-- ";
24 | public VideoPlayContoller videoPlayController;
25 | private View view;
26 | public IjkVideoView mVideoView;
27 | private Handler handler = new Handler();
28 |
29 | private View rView;
30 | private Context mContext;
31 | private boolean portrait;
32 |
33 | public VideoPlayView(Context context) {
34 | super(context);
35 | mContext = context;
36 | initViews();
37 | }
38 |
39 | public void setContext(Context context){
40 | mContext = context;
41 | videoPlayController = new VideoPlayContoller(mContext, rView);
42 | }
43 |
44 | private void initViews() {
45 |
46 | rView = LayoutInflater.from(mContext).inflate(R.layout.view_video_item, this, true);
47 | view = findViewById(R.id.media_contoller);
48 | mVideoView = (IjkVideoView) findViewById(R.id.main_video);
49 | videoPlayController = new VideoPlayContoller(mContext, rView);
50 | mVideoView.setMediaController(videoPlayController);
51 | mVideoView.setOnCompletionListener(new IMediaPlayer.OnCompletionListener() {
52 | @Override
53 | public void onCompletion(IMediaPlayer mp) {
54 | view.setVisibility(View.GONE);
55 | if (videoPlayController.getScreenOrientation((Activity) mContext)
56 | == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
57 | //横屏播放完毕,重置
58 | ((Activity) mContext).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
59 | ViewGroup.LayoutParams layoutParams = getLayoutParams();
60 | layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
61 | layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
62 | setLayoutParams(layoutParams);
63 | }
64 | if (completionListener != null)
65 | completionListener.completion(mp);
66 | }
67 | });
68 |
69 | }
70 |
71 |
72 | public boolean isPlay() {
73 | return mVideoView.isPlaying();
74 | }
75 |
76 | public void pause() {
77 | if (mVideoView.isPlaying()) {
78 | mVideoView.pause();
79 | } else {
80 | mVideoView.start();
81 | }
82 | }
83 |
84 | public void start(String video_url, String title) {
85 | Uri uri = Uri.parse(video_url);
86 | if (videoPlayController != null)
87 | videoPlayController.setTitle(title);
88 | videoPlayController.start();
89 |
90 | mVideoView.stopPlayback();
91 | mVideoView.setVideoURI(uri);
92 | mVideoView.start();
93 | }
94 |
95 |
96 | public void start(){
97 | if (mVideoView.isPlaying()){
98 | mVideoView.start();
99 | }
100 | }
101 |
102 | public void setContorllerVisiable(){
103 | videoPlayController.setVisiable();
104 | }
105 |
106 | public void seekTo(int msec){
107 | mVideoView.seekTo(msec);
108 | }
109 |
110 | public void onChanged(Configuration configuration) {
111 | portrait = configuration.orientation == Configuration.ORIENTATION_PORTRAIT;
112 | doOnConfigurationChanged(portrait);
113 | }
114 |
115 | public void doOnConfigurationChanged(final boolean portrait) {
116 | if (mVideoView != null) {
117 | handler.post(new Runnable() {
118 | @Override
119 | public void run() {
120 | setFullScreen(!portrait);
121 | if (portrait) {
122 | ViewGroup.LayoutParams layoutParams = getLayoutParams();
123 | layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
124 | layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
125 | // LogUtil.e(TAG+"handler "+ "400");
126 | setLayoutParams(layoutParams);
127 | requestLayout();
128 | } else {
129 | int heightPixels = ((Activity) mContext).getResources().getDisplayMetrics().heightPixels;
130 | int widthPixels = ((Activity) mContext).getResources().getDisplayMetrics().widthPixels;
131 | ViewGroup.LayoutParams layoutParams = getLayoutParams();
132 | layoutParams.height = heightPixels;
133 | layoutParams.width = widthPixels;
134 | // LogUtil.e(TAG+"handler "+ "height==" + heightPixels + "\nwidth==" + widthPixels);
135 | setLayoutParams(layoutParams);
136 | }
137 | }
138 | });
139 | // orientationEventListener.enable();
140 | }
141 | }
142 |
143 | public void stop() {
144 | if (mVideoView.isPlaying()) {
145 | mVideoView.stopPlayback();
146 | }
147 | }
148 |
149 | public void stopPlayVideo() {
150 | if (this != null) {
151 | mVideoView.stopPlayback();
152 | }
153 | }
154 |
155 | public void showView() {
156 | ViewGroup last = (ViewGroup) this.getParent();//找到videoitemview的父类,然后remove
157 | if (last != null) {
158 | last.removeAllViews();
159 | View itemView = (View) last.getParent();
160 | if (itemView != null) {
161 | View viewById = itemView.findViewById(R.id.showview);
162 | if (viewById != null)
163 | viewById.setVisibility(View.VISIBLE);
164 | }
165 | }
166 | }
167 |
168 |
169 | public void stopVideo() {
170 | if (this != null) {
171 | showView();
172 | stop();
173 | release();
174 | }
175 | }
176 |
177 | public void onDestroy() {
178 | handler.removeCallbacksAndMessages(null);
179 | // orientationEventListener.disable();
180 | }
181 |
182 | private void setFullScreen(boolean fullScreen) {
183 | if (mContext != null && mContext instanceof Activity) {
184 | WindowManager.LayoutParams attrs = ((Activity) mContext).getWindow().getAttributes();
185 | if (fullScreen) {
186 | attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
187 | ((Activity) mContext).getWindow().setAttributes(attrs);
188 | ((Activity) mContext).getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
189 | } else {
190 | attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
191 | ((Activity) mContext).getWindow().setAttributes(attrs);
192 | ((Activity) mContext).getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
193 | }
194 | }
195 |
196 | }
197 |
198 | public void setShowContoller(boolean isShowContoller) {
199 | videoPlayController.setShowContoller(isShowContoller);
200 | }
201 |
202 | @Override
203 | public void onBufferingUpdate(MediaPlayer mp, int percent) {
204 |
205 | }
206 |
207 | @Override
208 | public boolean onInfo(MediaPlayer mp, int what, int extra) {
209 | return false;
210 | }
211 |
212 | public long getPalyPostion() {
213 | return mVideoView.getCurrentPosition();
214 | }
215 |
216 | public void release() {
217 | mVideoView.release(true);
218 | }
219 |
220 | public int VideoStatus() {
221 | return mVideoView.getCurrentStatue();
222 | }
223 |
224 | private CompletionListener completionListener;
225 |
226 | public void setCompletionListener(CompletionListener completionListener) {
227 | this.completionListener = completionListener;
228 | }
229 | public interface CompletionListener {
230 | void completion(IMediaPlayer mp);
231 | }
232 | }
233 |
--------------------------------------------------------------------------------
/app/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | generateDebugAndroidTestSources
19 | generateDebugSources
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 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/java/js/nch/videoplay/FullScreenTouch.java:
--------------------------------------------------------------------------------
1 | package js.nch.videoplay;
2 |
3 | import android.app.Activity;
4 | import android.app.Dialog;
5 | import android.content.Context;
6 | import android.media.AudioManager;
7 | import android.view.LayoutInflater;
8 | import android.view.MotionEvent;
9 | import android.view.View;
10 | import android.view.View.OnTouchListener;
11 | import android.view.Window;
12 | import android.view.WindowManager;
13 | import android.widget.ImageView;
14 | import android.widget.ProgressBar;
15 | import android.widget.TextView;
16 |
17 |
18 | /**
19 | * 控制全屏音量跟进度条的触摸事件
20 | * Created by peter on 16/8/31.
21 | */
22 | public class FullScreenTouch implements OnTouchListener {
23 |
24 | private final Activity activity;
25 | private boolean isChangeVolume;
26 | private VideoPlayView videoPlayView ;
27 |
28 | private ProgressBar mDialogProgressBar;//进度条
29 | private TextView mDialogCurrentTime;
30 | private TextView mDialogTotalTime;
31 | private ImageView mDialogIcon;
32 | public Dialog mProgressDialog;
33 | public Dialog mVolumeDialog;
34 | private int mResultTimePosition;
35 | private ProgressBar mDialogVolumeProgressBar;
36 | private float mDownX;
37 | private float mDownY;
38 | private boolean mChangeVolume;
39 | private boolean mChangePosition;
40 | private int mDownPosition;
41 | private AudioManager mAudioManager;
42 | private int mDownVolume;
43 | private int mScreenWidth;
44 | private int mScreenHeight;
45 | protected int mThreshold = 80;
46 |
47 |
48 | public FullScreenTouch(Activity activity ,boolean isChangeVolume) {
49 | this.isChangeVolume = isChangeVolume;
50 | this.activity = activity;
51 | mAudioManager = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
52 | mScreenWidth = activity.getResources().getDisplayMetrics().widthPixels;
53 | mScreenHeight = activity.getResources().getDisplayMetrics().heightPixels;
54 | videoPlayView = VideoPlayViewManage.getManage().initialize(activity);
55 | }
56 |
57 |
58 | @Override
59 | public boolean onTouch(View v, MotionEvent event) {
60 | float x = event.getX();
61 | float y = event.getY();
62 | switch (event.getAction()) {
63 | case MotionEvent.ACTION_DOWN:
64 | mDownX = x;
65 | mDownY = y;
66 | mChangeVolume = false;
67 | mChangePosition = false;
68 | break;
69 | case MotionEvent.ACTION_MOVE:
70 | float deltaX = x - mDownX;
71 | float deltaY = y - mDownY;
72 | float absDeltaX = Math.abs(deltaX);
73 | float absDeltaY = Math.abs(deltaY);
74 |
75 | if (!mChangePosition && !mChangeVolume) {
76 | if (absDeltaX > mThreshold || absDeltaY > mThreshold) {
77 | if (absDeltaX >= mThreshold) {
78 | mChangePosition = true;
79 | mDownPosition = getCurrentPositionWhenPlaying();
80 | } else {
81 | mChangeVolume = true;
82 | mDownVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
83 | }
84 | }
85 | }
86 | if (mChangePosition) {
87 | showProgressDialog(deltaX);
88 | }
89 | if (mChangeVolume) {
90 | if (isChangeVolume) {
91 | showVolumDialog(-deltaY);
92 | }
93 | }
94 |
95 | break;
96 | case MotionEvent.ACTION_UP:
97 | if (mProgressDialog != null) {
98 | mProgressDialog.dismiss();
99 | }
100 | if (mVolumeDialog != null) {
101 | mVolumeDialog.dismiss();
102 | }
103 | if (mChangePosition) {
104 |
105 | videoPlayView.mVideoView.seekTo(mResultTimePosition);
106 | int duration = getDuration();
107 | int progress = mResultTimePosition * 100 / (duration == 0 ? 1 : duration);
108 | videoPlayView.videoPlayController.seekBar.setProgress(progress);
109 | }
110 |
111 | break;
112 |
113 | }
114 |
115 | return true;
116 | }
117 |
118 | protected int getCurrentPositionWhenPlaying() {
119 | int position = 0;
120 | if (videoPlayView.mVideoView.isPlaying()) {
121 | try {
122 | position = videoPlayView.mVideoView.getCurrentPosition();
123 | } catch (IllegalStateException e) {
124 | e.printStackTrace();
125 | return position;
126 | }
127 | }
128 | return position;
129 | }
130 | /**
131 | * 显示加减进度
132 | *
133 | * @param deltaX
134 | */
135 | protected void showProgressDialog(float deltaX) {
136 | if (mProgressDialog == null) {
137 | View localView = LayoutInflater.from(activity).inflate(R.layout.uu_progress_dialog, null);
138 | mDialogProgressBar = ((ProgressBar) localView.findViewById(R.id.duration_progressbar));
139 | mDialogCurrentTime = ((TextView) localView.findViewById(R.id.tv_current));
140 | mDialogTotalTime = ((TextView) localView.findViewById(R.id.tv_duration));
141 | mDialogIcon = ((ImageView) localView.findViewById(R.id.duration_image_tip));
142 | mProgressDialog = new Dialog(activity, R.style.uu_style_dialog_progress);
143 | mProgressDialog.setContentView(localView);
144 | mProgressDialog.getWindow().addFlags(Window.FEATURE_ACTION_BAR);
145 | mProgressDialog.getWindow().addFlags(32);
146 | mProgressDialog.getWindow().addFlags(16);
147 | mProgressDialog.getWindow().setLayout(-2, -2);
148 | WindowManager.LayoutParams localLayoutParams = mProgressDialog.getWindow().getAttributes();
149 | localLayoutParams.gravity = 49;
150 | localLayoutParams.y = activity.getResources().getDimensionPixelOffset(R.dimen.uu_progress_dialog_margin_top);
151 | mProgressDialog.getWindow().setAttributes(localLayoutParams);
152 | }
153 | if (!mProgressDialog.isShowing()) {
154 | mProgressDialog.show();
155 | }
156 | int totalTime = getDuration();
157 | mResultTimePosition = (int) (mDownPosition + deltaX * totalTime / mScreenWidth);
158 | if (mResultTimePosition > totalTime) mResultTimePosition = totalTime;
159 | mDialogCurrentTime.setText(Utils.stringForTime(mResultTimePosition));
160 | mDialogTotalTime.setText(" / " + Utils.stringForTime(totalTime) + "");
161 | mDialogProgressBar.setProgress(mResultTimePosition * 100 / totalTime);
162 | if (deltaX > 0) {
163 | mDialogIcon.setBackgroundResource(R.drawable.uu_forward_icon);
164 | } else {
165 | mDialogIcon.setBackgroundResource(R.drawable.uu_backward_icon);
166 | }
167 | }
168 |
169 | /**
170 | * 显示音量加减
171 | *
172 | * @param deltaY
173 | */
174 | protected void showVolumDialog(float deltaY) {
175 | if (mVolumeDialog == null) {
176 | View localView = LayoutInflater.from(activity).inflate(R.layout.uu_volume_dialog, null);
177 | mDialogVolumeProgressBar = ((ProgressBar) localView.findViewById(R.id.volume_progressbar));
178 | mVolumeDialog = new Dialog(activity, R.style.uu_style_dialog_progress);
179 | mVolumeDialog.setContentView(localView);
180 | mVolumeDialog.getWindow().addFlags(8);
181 | mVolumeDialog.getWindow().addFlags(32);
182 | mVolumeDialog.getWindow().addFlags(16);
183 | mVolumeDialog.getWindow().setLayout(-2, -2);
184 | WindowManager.LayoutParams localLayoutParams = mVolumeDialog.getWindow().getAttributes();
185 | localLayoutParams.gravity = 19;
186 | localLayoutParams.x = activity.getResources().getDimensionPixelOffset(R.dimen.uu_volume_dialog_margin_left);
187 | mVolumeDialog.getWindow().setAttributes(localLayoutParams);
188 | }
189 | if (!mVolumeDialog.isShowing()) {
190 | mVolumeDialog.show();
191 | }
192 | int max = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
193 | int deltaV = (int) (max * deltaY * 3 / mScreenHeight);
194 | mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mDownVolume + deltaV, 0);
195 | int transformatVolume = (int) (mDownVolume * 100 / max + deltaY * 3 * 100 / mScreenHeight);
196 | mDialogVolumeProgressBar.setProgress(transformatVolume);
197 | }
198 |
199 | public int getDuration() {
200 | int duration = 0;
201 | try {
202 | duration = videoPlayView.mVideoView.getDuration();
203 | } catch (IllegalStateException e) {
204 | e.printStackTrace();
205 | return duration;
206 | }
207 | return duration;
208 | }
209 |
210 | }
211 |
--------------------------------------------------------------------------------
/ListVideoPlay/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | generateDebugAndroidTestSources
19 | generateDebugSources
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 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/java/js/nch/videoplay/video/SurfaceRenderView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Zhang Rui
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package js.nch.videoplay.video;
18 |
19 | import android.annotation.TargetApi;
20 | import android.content.Context;
21 | import android.graphics.SurfaceTexture;
22 | import android.os.Build;
23 | import android.support.annotation.NonNull;
24 | import android.support.annotation.Nullable;
25 | import android.util.AttributeSet;
26 | import android.util.Log;
27 | import android.view.Surface;
28 | import android.view.SurfaceHolder;
29 | import android.view.SurfaceView;
30 | import android.view.View;
31 | import android.view.accessibility.AccessibilityEvent;
32 | import android.view.accessibility.AccessibilityNodeInfo;
33 |
34 | import java.lang.ref.WeakReference;
35 | import java.util.Map;
36 | import java.util.concurrent.ConcurrentHashMap;
37 |
38 | import tv.danmaku.ijk.media.player.IMediaPlayer;
39 | import tv.danmaku.ijk.media.player.ISurfaceTextureHolder;
40 |
41 | public class SurfaceRenderView extends SurfaceView implements IRenderView {
42 | private MeasureHelper mMeasureHelper;
43 |
44 | public SurfaceRenderView(Context context) {
45 | super(context);
46 | initView(context);
47 | }
48 |
49 | public SurfaceRenderView(Context context, AttributeSet attrs) {
50 | super(context, attrs);
51 | initView(context);
52 | }
53 |
54 | public SurfaceRenderView(Context context, AttributeSet attrs, int defStyleAttr) {
55 | super(context, attrs, defStyleAttr);
56 | initView(context);
57 | }
58 |
59 | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
60 | public SurfaceRenderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
61 | super(context, attrs, defStyleAttr, defStyleRes);
62 | initView(context);
63 | }
64 |
65 | private void initView(Context context) {
66 | mMeasureHelper = new MeasureHelper(this);
67 | mSurfaceCallback = new SurfaceCallback(this);
68 | getHolder().addCallback(mSurfaceCallback);
69 | //noinspection deprecation
70 | getHolder().setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
71 | }
72 |
73 | @Override
74 | public View getView() {
75 | return this;
76 | }
77 |
78 | @Override
79 | public boolean shouldWaitForResize() {
80 | return true;
81 | }
82 |
83 | //--------------------
84 | // Layout & Measure
85 | //--------------------
86 | @Override
87 | public void setVideoSize(int videoWidth, int videoHeight) {
88 | if (videoWidth > 0 && videoHeight > 0) {
89 | mMeasureHelper.setVideoSize(videoWidth, videoHeight);
90 | getHolder().setFixedSize(videoWidth, videoHeight);
91 | requestLayout();
92 | }
93 | }
94 |
95 | @Override
96 | public void setVideoSampleAspectRatio(int videoSarNum, int videoSarDen) {
97 | if (videoSarNum > 0 && videoSarDen > 0) {
98 | mMeasureHelper.setVideoSampleAspectRatio(videoSarNum, videoSarDen);
99 | requestLayout();
100 | }
101 | }
102 |
103 | @Override
104 | public void setVideoRotation(int degree) {
105 | Log.e("", "SurfaceView doesn't support rotation (" + degree + ")!\n");
106 | }
107 |
108 | @Override
109 | public void setAspectRatio(int aspectRatio) {
110 | mMeasureHelper.setAspectRatio(aspectRatio);
111 | requestLayout();
112 | }
113 |
114 | @Override
115 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
116 | mMeasureHelper.doMeasure(widthMeasureSpec, heightMeasureSpec);
117 | setMeasuredDimension(mMeasureHelper.getMeasuredWidth(), mMeasureHelper.getMeasuredHeight());
118 | }
119 |
120 | //--------------------
121 | // SurfaceViewHolder
122 | //--------------------
123 |
124 | private static final class InternalSurfaceHolder implements IRenderView.ISurfaceHolder {
125 | private SurfaceRenderView mSurfaceView;
126 | private SurfaceHolder mSurfaceHolder;
127 |
128 | public InternalSurfaceHolder(@NonNull SurfaceRenderView surfaceView,
129 | @Nullable SurfaceHolder surfaceHolder) {
130 | mSurfaceView = surfaceView;
131 | mSurfaceHolder = surfaceHolder;
132 | }
133 |
134 | public void bindToMediaPlayer(IMediaPlayer mp) {
135 | if (mp != null) {
136 | if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) &&
137 | (mp instanceof ISurfaceTextureHolder)) {
138 | ISurfaceTextureHolder textureHolder = (ISurfaceTextureHolder) mp;
139 | textureHolder.setSurfaceTexture(null);
140 | }
141 | mp.setDisplay(mSurfaceHolder);
142 | }
143 | }
144 |
145 | @NonNull
146 | @Override
147 | public IRenderView getRenderView() {
148 | return mSurfaceView;
149 | }
150 |
151 | @Nullable
152 | @Override
153 | public SurfaceHolder getSurfaceHolder() {
154 | return mSurfaceHolder;
155 | }
156 |
157 | @Nullable
158 | @Override
159 | public SurfaceTexture getSurfaceTexture() {
160 | return null;
161 | }
162 |
163 | @Nullable
164 | @Override
165 | public Surface openSurface() {
166 | if (mSurfaceHolder == null)
167 | return null;
168 | return mSurfaceHolder.getSurface();
169 | }
170 | }
171 |
172 | //-------------------------
173 | // SurfaceHolder.Callback
174 | //-------------------------
175 |
176 | @Override
177 | public void addRenderCallback(IRenderCallback callback) {
178 | mSurfaceCallback.addRenderCallback(callback);
179 | }
180 |
181 | @Override
182 | public void removeRenderCallback(IRenderCallback callback) {
183 | mSurfaceCallback.removeRenderCallback(callback);
184 | }
185 |
186 | private SurfaceCallback mSurfaceCallback;
187 |
188 | private static final class SurfaceCallback implements SurfaceHolder.Callback {
189 | private SurfaceHolder mSurfaceHolder;
190 | private boolean mIsFormatChanged;
191 | private int mFormat;
192 | private int mWidth;
193 | private int mHeight;
194 |
195 | private WeakReference mWeakSurfaceView;
196 | private Map mRenderCallbackMap = new ConcurrentHashMap();
197 |
198 | public SurfaceCallback(@NonNull SurfaceRenderView surfaceView) {
199 | mWeakSurfaceView = new WeakReference(surfaceView);
200 | }
201 |
202 | public void addRenderCallback(@NonNull IRenderCallback callback) {
203 | mRenderCallbackMap.put(callback, callback);
204 |
205 | ISurfaceHolder surfaceHolder = null;
206 | if (mSurfaceHolder != null) {
207 | if (surfaceHolder == null)
208 | surfaceHolder = new InternalSurfaceHolder(mWeakSurfaceView.get(), mSurfaceHolder);
209 | callback.onSurfaceCreated(surfaceHolder, mWidth, mHeight);
210 | }
211 |
212 | if (mIsFormatChanged) {
213 | if (surfaceHolder == null)
214 | surfaceHolder = new InternalSurfaceHolder(mWeakSurfaceView.get(), mSurfaceHolder);
215 | callback.onSurfaceChanged(surfaceHolder, mFormat, mWidth, mHeight);
216 | }
217 | }
218 |
219 | public void removeRenderCallback(@NonNull IRenderCallback callback) {
220 | mRenderCallbackMap.remove(callback);
221 | }
222 |
223 | @Override
224 | public void surfaceCreated(SurfaceHolder holder) {
225 | mSurfaceHolder = holder;
226 | mIsFormatChanged = false;
227 | mFormat = 0;
228 | mWidth = 0;
229 | mHeight = 0;
230 |
231 | ISurfaceHolder surfaceHolder = new InternalSurfaceHolder(mWeakSurfaceView.get(), mSurfaceHolder);
232 | for (IRenderCallback renderCallback : mRenderCallbackMap.keySet()) {
233 | renderCallback.onSurfaceCreated(surfaceHolder, 0, 0);
234 | }
235 | }
236 |
237 | @Override
238 | public void surfaceDestroyed(SurfaceHolder holder) {
239 | mSurfaceHolder = null;
240 | mIsFormatChanged = false;
241 | mFormat = 0;
242 | mWidth = 0;
243 | mHeight = 0;
244 |
245 | ISurfaceHolder surfaceHolder = new InternalSurfaceHolder(mWeakSurfaceView.get(), mSurfaceHolder);
246 | for (IRenderCallback renderCallback : mRenderCallbackMap.keySet()) {
247 | renderCallback.onSurfaceDestroyed(surfaceHolder);
248 | }
249 | }
250 |
251 | @Override
252 | public void surfaceChanged(SurfaceHolder holder, int format,
253 | int width, int height) {
254 | mSurfaceHolder = holder;
255 | mIsFormatChanged = true;
256 | mFormat = format;
257 | mWidth = width;
258 | mHeight = height;
259 |
260 | // mMeasureHelper.setVideoSize(width, height);
261 |
262 | ISurfaceHolder surfaceHolder = new InternalSurfaceHolder(mWeakSurfaceView.get(), mSurfaceHolder);
263 | for (IRenderCallback renderCallback : mRenderCallbackMap.keySet()) {
264 | renderCallback.onSurfaceChanged(surfaceHolder, format, width, height);
265 | }
266 | }
267 | }
268 |
269 | //--------------------
270 | // Accessibility
271 | //--------------------
272 |
273 | @Override
274 | public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
275 | super.onInitializeAccessibilityEvent(event);
276 | event.setClassName(SurfaceRenderView.class.getName());
277 | }
278 |
279 | @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
280 | @Override
281 | public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
282 | super.onInitializeAccessibilityNodeInfo(info);
283 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
284 | info.setClassName(SurfaceRenderView.class.getName());
285 | }
286 | }
287 | }
288 |
--------------------------------------------------------------------------------
/app/src/main/java/js/listvideodemo/list/ListActivity.java:
--------------------------------------------------------------------------------
1 | package js.listvideodemo.list;
2 |
3 | import android.content.Intent;
4 | import android.content.res.Configuration;
5 | import android.os.Bundle;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.support.v7.widget.LinearLayoutManager;
8 | import android.support.v7.widget.RecyclerView;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.FrameLayout;
12 | import android.widget.RelativeLayout;
13 |
14 | import js.listvideodemo.R;
15 | import js.listvideodemo.playpage.PlayPageActivity;
16 | import js.nch.videoplay.FullScreenTouch;
17 | import js.nch.videoplay.VideoPlayView;
18 | import js.nch.videoplay.VideoPlayViewManage;
19 | import js.nch.videoplay.video.IjkVideoView;
20 | import tv.danmaku.ijk.media.player.IMediaPlayer;
21 |
22 | /**
23 | * Created by peter on 16/8/31.
24 | */
25 | public class ListActivity extends AppCompatActivity {
26 |
27 | private RecyclerView recyclerView;
28 | private RelativeLayout fullScreen;
29 | private ListVideoAdapter listVideoAdapter;
30 | private VideoPlayView videoPlayView;
31 | private LinearLayoutManager mLayoutManager;
32 | private int postion = -1;
33 | private int lastPostion = -1;
34 | private RelativeLayout onPlaypage;
35 | private boolean isStarActivity = false;
36 |
37 | @Override
38 | protected void onCreate(Bundle savedInstanceState) {
39 | super.onCreate(savedInstanceState);
40 | setContentView(R.layout.activity_list);
41 | videoPlayView = VideoPlayViewManage.getManage().initialize(this);
42 | initUI();
43 |
44 | initVideoPlay();
45 |
46 | }
47 | private void initUI() {
48 |
49 | recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
50 | fullScreen = (RelativeLayout) findViewById(R.id.full_screen);
51 | onPlaypage = (RelativeLayout) findViewById(R.id.on_playpage);
52 | mLayoutManager = new LinearLayoutManager(this);
53 | listVideoAdapter = new ListVideoAdapter(this);
54 | recyclerView.setAdapter(listVideoAdapter);
55 | recyclerView.setLayoutManager(mLayoutManager);
56 | }
57 | private void initVideoPlay() {
58 | onPlaypage.setVisibility(View.VISIBLE);
59 | onPlaypage.setOnClickListener(new View.OnClickListener() {
60 | @Override
61 | public void onClick(View v) {
62 | isStarActivity= true;
63 | startActivityForResult(new Intent(ListActivity.this,PlayPageActivity.class),100);
64 | }
65 | });
66 | fullScreen.setOnTouchListener(new FullScreenTouch(this,true));
67 | listVideoAdapter.setPlayClick(new ListVideoAdapter.onPlayClick() {
68 | @Override
69 | public void onPlayclick(int position, RelativeLayout image) {
70 | image.setVisibility(View.GONE);
71 | if (videoPlayView.isPlay() && lastPostion == position){
72 | return;
73 | }
74 |
75 | postion = position;
76 | if (videoPlayView.VideoStatus() == IjkVideoView.STATE_PAUSED) {
77 |
78 | if (position != lastPostion) {
79 | videoPlayView.stopPlayVideo();
80 | videoPlayView.release();
81 | }
82 | }
83 | if (lastPostion != -1) {
84 | videoPlayView.setShowContoller(true);
85 | videoPlayView.showView();
86 | }
87 |
88 | View view = recyclerView.findViewHolderForAdapterPosition(position).itemView;
89 | FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.layout_video);
90 | frameLayout.removeAllViews();
91 |
92 | videoPlayView.showView();
93 | frameLayout.addView(videoPlayView);
94 | videoPlayView.start("http://106.38.75.98:8092/video/2016/0901/12/b4fcb03e407bdc39.mp4","title");
95 | lastPostion = position;
96 | }
97 | });
98 | //播放完还原播放界面
99 | videoPlayView.setCompletionListener(new VideoPlayView.CompletionListener() {
100 | @Override
101 | public void completion(IMediaPlayer mp) {
102 |
103 | ViewGroup last = (ViewGroup) videoPlayView.getParent();//找到videoitemview的父类,然后remove
104 | if (last != null && last.getChildCount() > 0) {
105 | last.removeAllViews();
106 | View itemView = (View) last.getParent();
107 | if (itemView != null) {
108 | itemView.findViewById(R.id.showview).setVisibility(View.VISIBLE);
109 | }
110 | }
111 | }
112 | });
113 | //显示||关闭 小窗口
114 | recyclerView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {
115 | @Override
116 | public void onChildViewAttachedToWindow(View view) {
117 | int index = recyclerView.getChildAdapterPosition(view);
118 | view.findViewById(R.id.showview).setVisibility(View.VISIBLE);
119 | if (index == postion) {
120 |
121 | FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.layout_video);
122 | frameLayout.removeAllViews();
123 | if (videoPlayView != null &&
124 | ((videoPlayView.isPlay()) || videoPlayView.VideoStatus() == IjkVideoView.STATE_PAUSED)) {
125 | view.findViewById(R.id.showview).setVisibility(View.GONE);
126 | }
127 |
128 | if (videoPlayView.VideoStatus() == IjkVideoView.STATE_PAUSED) {
129 | if (videoPlayView.getParent() != null)
130 | ((ViewGroup) videoPlayView.getParent()).removeAllViews();
131 | frameLayout.addView(videoPlayView);
132 | return;
133 | }
134 | }
135 | }
136 |
137 | @Override
138 | public void onChildViewDetachedFromWindow(View view) {
139 | int index = recyclerView.getChildAdapterPosition(view);
140 | if (index == postion) {
141 | //是否删除小屏
142 | if (true) {
143 | if (videoPlayView != null) {
144 | videoPlayView.stop();
145 | videoPlayView.release();
146 | }
147 | }
148 | }
149 | }
150 | });
151 | }
152 |
153 |
154 |
155 |
156 | @Override
157 | public void onConfigurationChanged(Configuration newConfig) {
158 | super.onConfigurationChanged(newConfig);
159 | if (videoPlayView != null) {
160 | videoPlayView.onChanged(newConfig);
161 | if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
162 | fullScreen.setVisibility(View.GONE);
163 | fullScreen.removeAllViews();
164 | recyclerView.setVisibility(View.VISIBLE);
165 | if (postion <= mLayoutManager.findLastVisibleItemPosition()
166 | && postion >= mLayoutManager.findFirstVisibleItemPosition()) {
167 |
168 | View view = recyclerView.findViewHolderForAdapterPosition(postion).itemView;
169 | FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.layout_video);
170 | frameLayout.removeAllViews();
171 | ViewGroup last = (ViewGroup) videoPlayView.getParent();//找到videoitemview的父类,然后remove
172 | if (last != null) {
173 | last.removeAllViews();
174 | }
175 |
176 | frameLayout.addView(videoPlayView);
177 | videoPlayView.setShowContoller(true);
178 | } else {
179 | videoPlayView.setShowContoller(true);
180 | }
181 |
182 | videoPlayView.setContorllerVisiable();
183 | int mShowFlags =
184 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
185 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
186 | | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
187 | fullScreen.setSystemUiVisibility(mShowFlags);
188 | } else {
189 |
190 | ViewGroup viewGroup = (ViewGroup) videoPlayView.getParent();
191 | if (viewGroup == null)
192 | return;
193 | viewGroup.removeAllViews();
194 | fullScreen.addView(videoPlayView);
195 | fullScreen.setVisibility(View.VISIBLE);
196 | int mHideFlags =
197 | View.SYSTEM_UI_FLAG_LOW_PROFILE
198 | | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
199 | | View.SYSTEM_UI_FLAG_FULLSCREEN
200 | | View.SYSTEM_UI_FLAG_IMMERSIVE
201 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
202 | | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
203 | ;
204 | fullScreen.setSystemUiVisibility(mHideFlags);
205 | }
206 | } else {
207 | fullScreen.setVisibility(View.GONE);
208 | }
209 | }
210 |
211 | @Override
212 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
213 | super.onActivityResult(requestCode, resultCode, data);
214 | if (requestCode == 100){
215 | View view = recyclerView.findViewHolderForAdapterPosition(postion).itemView;
216 | FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.layout_video);
217 | frameLayout.removeAllViews();
218 | videoPlayView.showView();
219 | frameLayout.addView(videoPlayView);
220 | videoPlayView.setContorllerVisiable();
221 | }else {
222 | videoPlayView.release();
223 | final FrameLayout frameLayout = (FrameLayout) videoPlayView.getParent();
224 | if (frameLayout != null && frameLayout.getChildCount() > 0) {
225 | frameLayout.removeAllViews();
226 | View itemView = (View) frameLayout.getParent();
227 | if (itemView != null) {
228 | itemView.findViewById(R.id.showview).setVisibility(View.VISIBLE);
229 | }
230 | }
231 | }
232 | }
233 |
234 | @Override
235 | protected void onDestroy() {
236 | super.onDestroy();
237 | videoPlayView.stopPlayVideo();
238 | }
239 |
240 | @Override
241 | protected void onResume() {
242 | super.onResume();
243 | videoPlayView = VideoPlayViewManage.getManage().initialize(this);
244 | isStarActivity =false;
245 | }
246 |
247 | @Override
248 | protected void onPause() {
249 | super.onPause();
250 | if (!isStarActivity){
251 | videoPlayView.mVideoView.pause();
252 | }
253 | }
254 | }
255 |
--------------------------------------------------------------------------------
/ListVideoPlay/src/main/java/js/nch/videoplay/video/MeasureHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Zhang Rui
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package js.nch.videoplay.video;
18 |
19 | import android.content.Context;
20 | import android.support.annotation.NonNull;
21 | import android.view.View;
22 |
23 | import java.lang.ref.WeakReference;
24 |
25 | import js.nch.videoplay.R;
26 |
27 |
28 | public final class MeasureHelper {
29 | private WeakReference mWeakView;
30 |
31 | private int mVideoWidth;
32 | private int mVideoHeight;
33 | private int mVideoSarNum;
34 | private int mVideoSarDen;
35 |
36 | private int mVideoRotationDegree;
37 |
38 | private int mMeasuredWidth;
39 | private int mMeasuredHeight;
40 |
41 | private int mCurrentAspectRatio = IRenderView.AR_ASPECT_FIT_PARENT;
42 |
43 | public MeasureHelper(View view) {
44 | mWeakView = new WeakReference(view);
45 | }
46 |
47 | public View getView() {
48 | if (mWeakView == null)
49 | return null;
50 | return mWeakView.get();
51 | }
52 |
53 | public void setVideoSize(int videoWidth, int videoHeight) {
54 | mVideoWidth = videoWidth;
55 | mVideoHeight = videoHeight;
56 | }
57 |
58 | public void setVideoSampleAspectRatio(int videoSarNum, int videoSarDen) {
59 | mVideoSarNum = videoSarNum;
60 | mVideoSarDen = videoSarDen;
61 | }
62 |
63 | public void setVideoRotation(int videoRotationDegree) {
64 | mVideoRotationDegree = videoRotationDegree;
65 | }
66 |
67 | /**
68 | * Must be called by View.onMeasure(int, int)
69 | *
70 | * @param widthMeasureSpec
71 | * @param heightMeasureSpec
72 | */
73 | public void doMeasure(int widthMeasureSpec, int heightMeasureSpec) {
74 | //Log.i("@@@@", "onMeasure(" + MeasureSpec.toString(widthMeasureSpec) + ", "
75 | // + MeasureSpec.toString(heightMeasureSpec) + ")");
76 | if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) {
77 | int tempSpec = widthMeasureSpec;
78 | widthMeasureSpec = heightMeasureSpec;
79 | heightMeasureSpec = tempSpec;
80 | }
81 |
82 | int width = View.getDefaultSize(mVideoWidth, widthMeasureSpec);
83 | int height = View.getDefaultSize(mVideoHeight, heightMeasureSpec);
84 | if (mCurrentAspectRatio == IRenderView.AR_MATCH_PARENT) {
85 | width = widthMeasureSpec;
86 | height = heightMeasureSpec;
87 | } else if (mVideoWidth > 0 && mVideoHeight > 0) {
88 | int widthSpecMode = View.MeasureSpec.getMode(widthMeasureSpec);
89 | int widthSpecSize = View.MeasureSpec.getSize(widthMeasureSpec);
90 | int heightSpecMode = View.MeasureSpec.getMode(heightMeasureSpec);
91 | int heightSpecSize = View.MeasureSpec.getSize(heightMeasureSpec);
92 |
93 | if (widthSpecMode == View.MeasureSpec.AT_MOST && heightSpecMode == View.MeasureSpec.AT_MOST) {
94 | float specAspectRatio = (float) widthSpecSize / (float) heightSpecSize;
95 | float displayAspectRatio;
96 | switch (mCurrentAspectRatio) {
97 | case IRenderView.AR_16_9_FIT_PARENT:
98 | displayAspectRatio = 16.0f / 9.0f;
99 | if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270)
100 | displayAspectRatio = 1.0f / displayAspectRatio;
101 | break;
102 | case IRenderView.AR_4_3_FIT_PARENT:
103 | displayAspectRatio = 4.0f / 3.0f;
104 | if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270)
105 | displayAspectRatio = 1.0f / displayAspectRatio;
106 | break;
107 | case IRenderView.AR_ASPECT_FIT_PARENT:
108 | case IRenderView.AR_ASPECT_FILL_PARENT:
109 | case IRenderView.AR_ASPECT_WRAP_CONTENT:
110 | default:
111 | displayAspectRatio = (float) mVideoWidth / (float) mVideoHeight;
112 | if (mVideoSarNum > 0 && mVideoSarDen > 0)
113 | displayAspectRatio = displayAspectRatio * mVideoSarNum / mVideoSarDen;
114 | break;
115 | }
116 | boolean shouldBeWider = displayAspectRatio > specAspectRatio;
117 |
118 | switch (mCurrentAspectRatio) {
119 | case IRenderView.AR_ASPECT_FIT_PARENT:
120 | case IRenderView.AR_16_9_FIT_PARENT:
121 | case IRenderView.AR_4_3_FIT_PARENT:
122 | if (shouldBeWider) {
123 | // too wide, fix width
124 | width = widthSpecSize;
125 | height = (int) (width / displayAspectRatio);
126 | } else {
127 | // too high, fix height
128 | height = heightSpecSize;
129 | width = (int) (height * displayAspectRatio);
130 | }
131 | break;
132 | case IRenderView.AR_ASPECT_FILL_PARENT:
133 | if (shouldBeWider) {
134 | // not high enough, fix height
135 | height = heightSpecSize;
136 | width = (int) (height * displayAspectRatio);
137 | } else {
138 | // not wide enough, fix width
139 | width = widthSpecSize;
140 | height = (int) (width / displayAspectRatio);
141 | }
142 | break;
143 | case IRenderView.AR_ASPECT_WRAP_CONTENT:
144 | default:
145 | if (shouldBeWider) {
146 | // too wide, fix width
147 | width = Math.min(mVideoWidth, widthSpecSize);
148 | height = (int) (width / displayAspectRatio);
149 | } else {
150 | // too high, fix height
151 | height = Math.min(mVideoHeight, heightSpecSize);
152 | width = (int) (height * displayAspectRatio);
153 | }
154 | break;
155 | }
156 | } else if (widthSpecMode == View.MeasureSpec.EXACTLY && heightSpecMode == View.MeasureSpec.EXACTLY) {
157 | // the size is fixed
158 | width = widthSpecSize;
159 | height = heightSpecSize;
160 |
161 | // for compatibility, we adjust size based on aspect ratio
162 | if (mVideoWidth * height < width * mVideoHeight) {
163 | //Log.i("@@@", "image too wide, correcting");
164 | width = height * mVideoWidth / mVideoHeight;
165 | } else if (mVideoWidth * height > width * mVideoHeight) {
166 | //Log.i("@@@", "image too tall, correcting");
167 | height = width * mVideoHeight / mVideoWidth;
168 | }
169 | } else if (widthSpecMode == View.MeasureSpec.EXACTLY) {
170 | // only the width is fixed, adjust the height to match aspect ratio if possible
171 | width = widthSpecSize;
172 | height = width * mVideoHeight / mVideoWidth;
173 | if (heightSpecMode == View.MeasureSpec.AT_MOST && height > heightSpecSize) {
174 | // couldn't match aspect ratio within the constraints
175 | height = heightSpecSize;
176 | }
177 | } else if (heightSpecMode == View.MeasureSpec.EXACTLY) {
178 | // only the height is fixed, adjust the width to match aspect ratio if possible
179 | height = heightSpecSize;
180 | width = height * mVideoWidth / mVideoHeight;
181 | if (widthSpecMode == View.MeasureSpec.AT_MOST && width > widthSpecSize) {
182 | // couldn't match aspect ratio within the constraints
183 | width = widthSpecSize;
184 | }
185 | } else {
186 | // neither the width nor the height are fixed, try to use actual video size
187 | width = mVideoWidth;
188 | height = mVideoHeight;
189 | if (heightSpecMode == View.MeasureSpec.AT_MOST && height > heightSpecSize) {
190 | // too tall, decrease both width and height
191 | height = heightSpecSize;
192 | width = height * mVideoWidth / mVideoHeight;
193 | }
194 | if (widthSpecMode == View.MeasureSpec.AT_MOST && width > widthSpecSize) {
195 | // too wide, decrease both width and height
196 | width = widthSpecSize;
197 | height = width * mVideoHeight / mVideoWidth;
198 | }
199 | }
200 | } else {
201 | // no size yet, just adopt the given spec sizes
202 | }
203 |
204 | mMeasuredWidth = width;
205 | mMeasuredHeight = height;
206 | }
207 |
208 | public int getMeasuredWidth() {
209 | return mMeasuredWidth;
210 | }
211 |
212 | public int getMeasuredHeight() {
213 | return mMeasuredHeight;
214 | }
215 |
216 | public void setAspectRatio(int aspectRatio) {
217 | mCurrentAspectRatio = aspectRatio;
218 | }
219 |
220 | @NonNull
221 | public static String getAspectRatioText(Context context, int aspectRatio) {
222 | String text;
223 | switch (aspectRatio) {
224 | case IRenderView.AR_ASPECT_FIT_PARENT:
225 | text = context.getString(R.string.VideoView_ar_aspect_fit_parent);
226 | break;
227 | case IRenderView.AR_ASPECT_FILL_PARENT:
228 | text = context.getString(R.string.VideoView_ar_aspect_fill_parent);
229 | break;
230 | case IRenderView.AR_ASPECT_WRAP_CONTENT:
231 | text = context.getString(R.string.VideoView_ar_aspect_wrap_content);
232 | break;
233 | case IRenderView.AR_MATCH_PARENT:
234 | text = context.getString(R.string.VideoView_ar_match_parent);
235 | break;
236 | case IRenderView.AR_16_9_FIT_PARENT:
237 | text = context.getString(R.string.VideoView_ar_16_9_fit_parent);
238 | break;
239 | case IRenderView.AR_4_3_FIT_PARENT:
240 | text = context.getString(R.string.VideoView_ar_4_3_fit_parent);
241 | break;
242 | default:
243 | text = context.getString(R.string.N_A);
244 | break;
245 | }
246 | return text;
247 | }
248 | }
249 |
--------------------------------------------------------------------------------