├── .gitignore ├── .idea ├── modules.xml ├── modules │ └── SimplePlayer.iml └── vcs.xml ├── README.md ├── build.gradle ├── demo ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── video │ │ └── demo │ │ ├── DemoApp.java │ │ ├── MainActivity.java │ │ ├── ScreenConvertor.java │ │ ├── VideoAdapter.java │ │ └── VideoPagerAdapter.java │ └── res │ ├── layout │ ├── activity_main.xml │ ├── player_layout.xml │ ├── vh_video.xml │ └── vh_viewpager.xml │ ├── raw │ └── intro.mp4 │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── lib-simpleplayer ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── uis │ │ └── lib │ │ └── simpleplayer │ │ ├── OnScreenListener.java │ │ ├── PlayerLayout.java │ │ ├── PlayerStateCallback.java │ │ ├── Vlog.java │ │ ├── bitmap │ │ ├── OnBitmapListener.java │ │ └── PlayerBitmap.java │ │ └── player │ │ ├── BasePlayerLayout.java │ │ ├── PlayerCallback.java │ │ ├── PlayerComplete.java │ │ ├── PlayerControl.java │ │ ├── PlayerCounter.java │ │ ├── PlayerEntity.java │ │ ├── PlayerListener.java │ │ ├── PlayerUtils.java │ │ └── PlayerView.java │ └── res │ ├── drawable │ ├── bg_black_trans.xml │ ├── btn_video_back.xml │ ├── btn_video_close.xml │ ├── btn_video_restart.xml │ ├── color_bt_back.xml │ ├── color_pb_red.xml │ ├── color_pb_white.xml │ ├── color_pb_white_trans.xml │ ├── pb_video_gray.xml │ ├── pb_video_progress.xml │ ├── sbar_thumb_normal.xml │ ├── sbar_thumb_pressed.xml │ └── sbar_video_thumb.xml │ ├── layout │ └── video_player_layout.xml │ ├── mipmap-xhdpi │ ├── video_back_normal.png │ ├── video_back_pressed.png │ ├── video_close_normal.png │ ├── video_close_pressed.png │ ├── video_restart_normal.png │ └── video_restart_pressed.png │ ├── mipmap-xxhdpi │ ├── fullscreen_exit.png │ ├── fullscreen_start.png │ ├── video_pause.png │ ├── video_play.png │ └── video_play_s.png │ └── values │ ├── video_attrs.xml │ └── video_ids.xml ├── settings.gradle └── snapshot ├── 2017-1.png ├── 2017-11.png ├── 2017-12.png ├── 2017-2.png ├── 2017-3.png ├── device-2017-001.png ├── device-2017-002.png └── device-2017-003.png /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | .idea 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | gradlew.bat 10 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/modules/SimplePlayer.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SimplePlayer 2 | AD Player simulate Tmall(广告播放器,模仿天猫,支持全屏,支持在线和离线播放,支持RecyclerView) 3 | 4 | ### 手机自带的MediaPlayer,支持http,https,rtsp 5 | 6 | ### 播放器原理 7 | 1.只有唯一的MediaPlayer和Surface在工作,切换视频会复用,内存消耗非常小 8 | 3.Surface创建使用的是Application.Context,Actiivty关闭不会对其持有引用 9 | 3.全屏切换会复用Surface防止卡顿,MediaPlayer随url变化,只保持一个 10 | 4.全屏切换通过Windows.ID_ANDROID_CONTENT 加上一个viewgroup 11 | a.全屏横屏 12 | ViewGroup.setSystemUiVisibility(SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); 13 | Activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 14 | b.退出横屏 15 | ViewGroup.setSystemUiVisibility(SYSTEM_UI_FLAG_VISIBLE); 16 | Activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 17 | 18 | # Use 19 | compile 'com.uis:lib-simpleplayer:0.2.0' 20 | # Version 21 | 0.0.2 init library 22 | 0.0.5 fixed Databinding Confilect,make demo like Tmall 23 | 0.0.6 fixed fullscreen hide the thumb picture 24 | 0.0.7 fixed screen change,make video resize 25 | 0.1.4 fixed fullscreen bug, add network dnymic changed,add thumb scaleType and holder 26 | 0.1.6 fixed全屏小画面,支持销毁PlayerView 27 | 0.1.8 fixed全屏小画面不能自适应,自动销毁资源 28 | 0.2.0 stable 29 | # 效果图 30 | ![image](/snapshot/2017-1.png) 31 | 32 | ![image](/snapshot/2017-2.png) 33 | 34 | ![image](/snapshot/2017-3.png) 35 | 36 | ![image](/snapshot/2017-11.png) 37 | 38 | ![image](/snapshot/2017-12.png) 39 | 40 | ![image](/snapshot/device-2017-002.png) 41 | 42 | ![image](/snapshot/device-2017-003.png) -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | google() 6 | jcenter() 7 | } 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:2.3.3' 10 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' 11 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | //maven {url 'https://jcenter.bintray.com'} 20 | maven{url 'https://dl.bintray.com/sweet/maven'} 21 | } 22 | } 23 | 24 | task clean(type: Delete) { 25 | delete rootProject.buildDir 26 | } 27 | ext { 28 | compileVer = 23 29 | buildVer = '25.0.0' 30 | minVer = 19 31 | targetVer = 25 32 | supportVer = '24.2.1' 33 | } 34 | -------------------------------------------------------------------------------- /demo/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /demo/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion compileVer 5 | buildToolsVersion buildVer 6 | 7 | 8 | defaultConfig { 9 | applicationId "com.video.demo" 10 | minSdkVersion minVer 11 | targetSdkVersion targetVer 12 | versionCode 1 13 | versionName "1.0" 14 | ndk { 15 | //选择要添加的对应cpu类型的.so库。 16 | abiFilters 'armeabi'//'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64','armeabi' 17 | } 18 | } 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | dataBinding { 26 | enabled false 27 | } 28 | } 29 | 30 | dependencies { 31 | compile fileTree(dir: 'libs', include: ['*.jar']) 32 | compile 'com.android.support:recyclerview-v7:'+supportVer 33 | compile 'com.android.support:design:'+supportVer 34 | //compile 'com.facebook.fresco:fresco:1.5.0' 35 | compile project(':lib-simpleplayer') 36 | //compile 'com.uis:lib-simpleplayer:0.0.2' 37 | } 38 | -------------------------------------------------------------------------------- /demo/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/lhb/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 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /demo/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 16 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /demo/src/main/java/com/video/demo/DemoApp.java: -------------------------------------------------------------------------------- 1 | package com.video.demo; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.drawee.backends.pipeline.Fresco; 6 | import com.uis.lib.simpleplayer.Vlog; 7 | 8 | //import com.facebook.drawee.backends.pipeline.Fresco; 9 | 10 | /** 11 | * Created by lhb on 2017/7/25. 12 | */ 13 | 14 | public class DemoApp extends Application { 15 | @Override 16 | public void onCreate() { 17 | super.onCreate(); 18 | Vlog.enableDebug(); 19 | Fresco.initialize(this); 20 | } 21 | 22 | public final static String URL = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1511769786707&di=a903cd0bc48d1ba8c5da5e530708ab61&imgtype=0&src=http%3A%2F%2Fa.hiphotos.baidu.com%2Fimage%2Fpic%2Fitem%2F58ee3d6d55fbb2fbbb8058d8464a20a44723dc55.jpg"; 23 | 24 | public static String[] mUrl = { 25 | "https://lmbsy.qq.com/flv/140/144/n0025l026va.mp4?sdtfrom=v1103&guid=8bc05ce6e4511a28a4d1b44ed110ff6f&vkey=C9527C07C187684A3D8CE17094A6B9DBCBCDD3AF71E66197C0345A43A1E5999E233543F2717B0A6768E6B95FE7CB8C8C043E518C4FC405D7BBA3D3FBF2BC25BC7AAA94A4622BA6A716DD4FBBB72CEA6B28678DE718AAEA5EF8FF0C949BBC53B0272AC396B53981013AE721DF259D08F8989D5B7B4F612B7A&platform=2", 26 | "http://data.vod.itc.cn/?rb=1&prot=1&key=jbZhEJhlqlUN-Wj_HEI8BjaVqKNFvDrn&prod=flash&pt=1&new=/51/116/UdKGIuSjQIO8dynrybyS1E.mp4", 27 | "https://vdse.bdstatic.com//6a90cf9678713ea594a428a8c98d2b5f.mp4?authorization=bce-auth-v1%2Ffb297a5cc0fb434c971b8fa103e8dd7b%2F2017-05-11T09%3A02%3A31Z%2F-1%2F%2F385d02679b636d6e5dd150193a497b787d517afef0f6c0903350a85056408e59", 28 | "http://data.vod.itc.cn/?rb=1&prot=1&key=jbZhEJhlqlUN-Wj_HEI8BjaVqKNFvDrn&prod=flash&pt=1&new=/20/111/bOT648IiIIVJPS33wZpYWH.mp4", 29 | "http://jzvd.nathen.cn/6ea7357bc3fa4658b29b7933ba575008/fbbba953374248eb913cb1408dc61d85-5287d2089db37e62345123a1be272f8b.mp4", 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /demo/src/main/java/com/video/demo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.video.demo; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.LinearLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.view.View; 9 | import android.widget.Button; 10 | 11 | import com.uis.lib.simpleplayer.Vlog; 12 | import com.uis.lib.simpleplayer.player.PlayerUtils; 13 | import com.uis.lib.simpleplayer.PlayerLayout; 14 | 15 | import java.io.File; 16 | import java.io.FileOutputStream; 17 | import java.io.InputStream; 18 | import java.io.OutputStream; 19 | 20 | public class MainActivity extends AppCompatActivity { 21 | 22 | String[] mIcon = {"http://pic.qiantucdn.com/58pic/19/59/29/86g58PICRd3_1024.jpg", 23 | "http://pic.90sjimg.com/back_pic/qk/back_origin_pic/00/03/14/c0391a6c1efab3fe00911b04e8cedca4.jpg"}; 24 | 25 | @Override 26 | protected void onCreate(Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | setContentView(R.layout.activity_main); 29 | PlayerLayout playerLayout = id(R.id.player_id); 30 | RecyclerView recyclerView = id(R.id.recycler_view); 31 | Button btOpen = id(R.id.bt_open); 32 | btOpen.setOnClickListener(new View.OnClickListener() { 33 | @Override 34 | public void onClick(View v) { 35 | startActivity(new Intent(v.getContext(),MainActivity.class)); 36 | } 37 | }); 38 | boolean isList = true; 39 | if(isList) { 40 | playerLayout.setVisibility(View.GONE); 41 | LinearLayoutManager layoutManager = new LinearLayoutManager(this); 42 | recyclerView.setLayoutManager(layoutManager); 43 | VideoAdapter adapter = new VideoAdapter(); 44 | int size = DemoApp.mUrl.length; 45 | String[] data = new String[1*size+2]; 46 | data[0] = ""; 47 | for(int i = 1,t = 1*size+1;i 0) { 59 | os.write(buff); 60 | } 61 | os.flush(); 62 | os.close(); 63 | is.close(); 64 | } 65 | }catch (Exception ex){ 66 | ex.printStackTrace(); 67 | } 68 | adapter.setData(data); 69 | recyclerView.setAdapter(adapter); 70 | }else{ 71 | playerLayout.start(DemoApp.mUrl[2],""); 72 | } 73 | 74 | } 75 | 76 | @Override 77 | protected void onDestroy() { 78 | PlayerUtils.release(); 79 | super.onDestroy(); 80 | } 81 | 82 | @Override 83 | protected void onResume() { 84 | super.onResume(); 85 | if(ScreenConvertor.isPlaying()) { 86 | //PlayerUtils.start(); 87 | } 88 | } 89 | 90 | @Override 91 | protected void onPause() { 92 | super.onPause(); 93 | ScreenConvertor.setPlaying(); 94 | PlayerUtils.pause(); 95 | } 96 | 97 | @Override 98 | public void onBackPressed() { 99 | if(!ScreenConvertor.onBackPressed(this)){ 100 | super.onBackPressed(); 101 | } 102 | } 103 | 104 | public T id(int id){ 105 | return (T)findViewById(id); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /demo/src/main/java/com/video/demo/ScreenConvertor.java: -------------------------------------------------------------------------------- 1 | package com.video.demo; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.pm.ActivityInfo; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.view.Window; 9 | import android.widget.FrameLayout; 10 | import com.uis.lib.simpleplayer.PlayerLayout; 11 | import com.uis.lib.simpleplayer.player.PlayerUtils; 12 | import java.util.Observer; 13 | 14 | /** 15 | * 屏幕视图变换器 16 | * @author uis on 2017/12/1. 17 | */ 18 | 19 | public class ScreenConvertor { 20 | 21 | private static boolean isPlaying; 22 | private static Observer sObserver; 23 | 24 | static void deleteObserver(){ 25 | sObserver = null; 26 | } 27 | 28 | static void notifyobserver(Object data){ 29 | if(sObserver != null){ 30 | sObserver.update(null,data); 31 | } 32 | } 33 | 34 | public static void setObserver(Observer observer){ 35 | sObserver = observer; 36 | } 37 | 38 | public static void setPlaying(){ 39 | isPlaying = PlayerUtils.isPlaying(); 40 | } 41 | 42 | public static boolean isPlaying(){ 43 | return isPlaying; 44 | } 45 | 46 | /** 47 | * 设置全屏播放 48 | * @param canPlay true:全屏,false:独立页面 49 | * @param layout 50 | */ 51 | public static void setFullScreen(boolean canPlay,PlayerLayout layout){ 52 | if(layout == null || !(layout.getContext() instanceof Activity)){ 53 | return; 54 | } 55 | Activity ac = (Activity)layout.getContext(); 56 | ViewGroup out = (ViewGroup)ac.findViewById(R.id.video_outside_id); 57 | boolean isOutSide = out.getChildCount() == 0; 58 | if(canPlay && isOutSide){//全屏播放 59 | layout.controlFullScreen(); 60 | }else{//独立页面播放 61 | createFullScreen(ac); 62 | } 63 | } 64 | 65 | public static boolean onBackPressed(Context mc){ 66 | return PlayerLayout.onBackPressed(mc) || destroyFullScreen(mc); 67 | } 68 | 69 | public static boolean destroyFullScreen(Context mc){ 70 | if(mc!=null && mc instanceof Activity) { 71 | Activity ac = (Activity) mc; 72 | ViewGroup vg = (ViewGroup)ac.findViewById(Window.ID_ANDROID_CONTENT); 73 | ViewGroup out = (ViewGroup)ac.findViewById(R.id.video_outside_id); 74 | View container = vg.findViewById(R.id.video_container_id); 75 | if (container != null && out != null && out.getChildCount()==0) { 76 | PlayerUtils.showActionBar(ac); 77 | vg.removeView(container); 78 | out.addView(container); 79 | notifyobserver(null); 80 | deleteObserver(); 81 | container.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); 82 | ac.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 83 | return true; 84 | } 85 | } 86 | return false; 87 | } 88 | 89 | static void createFullScreen(Activity ac){ 90 | ViewGroup vg = (ViewGroup)ac.findViewById(Window.ID_ANDROID_CONTENT); 91 | ViewGroup out = (ViewGroup)ac.findViewById(R.id.video_outside_id); 92 | final View container = vg.findViewById(R.id.video_container_id); 93 | if(container != null && out != null && out.getChildCount()>0) { 94 | PlayerUtils.hideActionBar(ac); 95 | out.removeView(container); 96 | FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( 97 | FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT); 98 | vg.addView(container,params); 99 | notifyobserver("true"); 100 | container.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() { 101 | @Override 102 | public void onSystemUiVisibilityChange(int visibility) { 103 | if(sObserver!=null){ 104 | setViewFullScreen(container); 105 | } 106 | } 107 | }); 108 | setViewFullScreen(container); 109 | ac.setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 110 | } 111 | } 112 | 113 | static void setViewFullScreen(View v){ 114 | if(v != null) { 115 | v.setSystemUiVisibility( 116 | View.SYSTEM_UI_FLAG_FULLSCREEN 117 | |View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 118 | ); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /demo/src/main/java/com/video/demo/VideoAdapter.java: -------------------------------------------------------------------------------- 1 | package com.video.demo; 2 | 3 | import android.support.v4.view.ViewPager; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.text.TextUtils; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | import com.uis.lib.simpleplayer.Vlog; 11 | import com.uis.lib.simpleplayer.PlayerLayout; 12 | 13 | /** 14 | * @author uis on 2017/11/17. 15 | */ 16 | 17 | public class VideoAdapter extends RecyclerView.Adapter { 18 | 19 | private String[] data; 20 | 21 | public VideoAdapter() { 22 | super(); 23 | } 24 | 25 | public void setData(String[] data){ 26 | this.data = data; 27 | } 28 | 29 | @Override 30 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 31 | View v; 32 | RecyclerView.ViewHolder vh; 33 | if(viewType==0) { 34 | v = LayoutInflater.from(parent.getContext()).inflate(R.layout.vh_video, parent, false); 35 | vh = new VideoVH(v); 36 | }else{ 37 | v = LayoutInflater.from(parent.getContext()).inflate(R.layout.vh_viewpager, parent, false); 38 | vh = new VpVH(v); 39 | } 40 | return vh; 41 | } 42 | 43 | @Override 44 | public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 45 | if(holder instanceof VideoVH){ 46 | ((VideoVH)holder).onViewBind(data[position]); 47 | }else if(holder instanceof VpVH){ 48 | ((VpVH)holder).onViewBind(); 49 | } 50 | } 51 | 52 | @Override 53 | public void onViewRecycled(RecyclerView.ViewHolder holder) { 54 | if(holder instanceof VideoVH){ 55 | ((VideoVH)holder).onViewRecycled(); 56 | } 57 | super.onViewRecycled(holder); 58 | } 59 | 60 | @Override 61 | public int getItemViewType(int position) { 62 | String pos = data[position]; 63 | return TextUtils.isEmpty(pos)?1:0; 64 | } 65 | 66 | @Override 67 | public int getItemCount() { 68 | return data==null?0:data.length; 69 | } 70 | 71 | static class VpVH extends RecyclerView.ViewHolder{ 72 | ViewPager viewPager; 73 | VideoPagerAdapter adapter; 74 | 75 | public VpVH(View itemView) { 76 | super(itemView); 77 | this.viewPager = id(itemView,R.id.viewpager); 78 | } 79 | 80 | public void onViewBind(){ 81 | Vlog.e("xx","onViewBind..."); 82 | if(adapter == null) { 83 | adapter = new VideoPagerAdapter(); 84 | viewPager.setOffscreenPageLimit(7); 85 | viewPager.addOnPageChangeListener(adapter); 86 | viewPager.setAdapter(adapter); 87 | } 88 | } 89 | } 90 | 91 | static class VideoVH extends RecyclerView.ViewHolder{ 92 | PlayerLayout player; 93 | String videoUrl; 94 | 95 | public VideoVH(View itemView) { 96 | super(itemView); 97 | player = id(itemView,R.id.player); 98 | } 99 | 100 | public void onViewRecycled(){ 101 | Vlog.e("xx","onViewRecycled..."); 102 | } 103 | 104 | public void onViewBind(String url){ 105 | Vlog.e("xx","onViewBind..."); 106 | player.start(url,DemoApp.URL); 107 | } 108 | } 109 | 110 | public static T id(View view,int id){ 111 | return (T)view.findViewById(id); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /demo/src/main/java/com/video/demo/VideoPagerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.video.demo; 2 | 3 | import android.app.Activity; 4 | import android.content.res.Resources; 5 | import android.support.v4.view.PagerAdapter; 6 | import android.support.v4.view.ViewPager; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.view.Window; 10 | 11 | import com.facebook.drawee.view.SimpleDraweeView; 12 | import com.uis.lib.simpleplayer.OnScreenListener; 13 | import com.uis.lib.simpleplayer.PlayerLayout; 14 | import com.uis.lib.simpleplayer.PlayerStateCallback; 15 | import com.uis.lib.simpleplayer.Vlog; 16 | import com.uis.lib.simpleplayer.player.PlayerComplete; 17 | import com.uis.lib.simpleplayer.player.PlayerUtils; 18 | 19 | import java.util.LinkedList; 20 | import java.util.Observable; 21 | import java.util.Observer; 22 | 23 | /** 24 | * @author uis on 2017/11/22. 25 | */ 26 | 27 | public class VideoPagerAdapter extends PagerAdapter implements ViewPager.OnPageChangeListener,Observer{ 28 | 29 | private LinkedList mList = new LinkedList<>(); 30 | private PlayerLayout mVideo; 31 | private final int WIDTH; 32 | private int currentPos; 33 | private boolean canVisibility; 34 | private View ivClose; 35 | private View vState; 36 | 37 | 38 | public VideoPagerAdapter() { 39 | canVisibility = false; 40 | currentPos = 0; 41 | WIDTH = Resources.getSystem().getDisplayMetrics().widthPixels; 42 | ScreenConvertor.setPlaying(); 43 | } 44 | 45 | @Override 46 | public Object instantiateItem(ViewGroup container, final int position) { 47 | View v; 48 | if(position>0) { 49 | if (mList.size() > 0) { 50 | v = mList.pop(); 51 | }else { 52 | v = new SimpleDraweeView(container.getContext()); 53 | ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(-1, WIDTH); 54 | v.setLayoutParams(params); 55 | } 56 | SimpleDraweeView sdView = (SimpleDraweeView)v; 57 | sdView.setOnClickListener(new View.OnClickListener() { 58 | @Override 59 | public void onClick(View v) { 60 | changeScreen(false); 61 | } 62 | }); 63 | sdView.setImageURI(DemoApp.URL); 64 | }else{ 65 | if(mVideo == null) { 66 | mVideo = new PlayerLayout(container.getContext()); 67 | mVideo.setPlayerStateCallback(new PlayerStateCallback() { 68 | @Override 69 | public void onState(int state) { 70 | //Vlog.a("xx","state = " + state); 71 | if(state == PlayerComplete.STATE_START){ 72 | vState.setVisibility(View.GONE); 73 | }else if(state == PlayerComplete.STATE_RESET || state == PlayerComplete.STATE_RELEASE){ 74 | if(!canVisibility) { 75 | vState.setVisibility(View.VISIBLE); 76 | } 77 | } 78 | } 79 | }); 80 | ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(-1, WIDTH); 81 | mVideo.setLayoutParams(params); 82 | String url = DemoApp.mUrl[2]; 83 | mVideo.start(position >= 0 ? url : "", DemoApp.URL); 84 | mVideo.setOnScreenListener(new OnScreenListener() { 85 | @Override 86 | public void onScreen(boolean isFullScreen) {//点击了放大 87 | changeScreen(true); 88 | } 89 | }); 90 | Activity ac = (Activity)container.getContext(); 91 | ViewGroup vg = (ViewGroup)ac.findViewById(Window.ID_ANDROID_CONTENT); 92 | final View cv = vg.findViewById(R.id.video_container_id); 93 | ivClose = cv.findViewById(R.id.video_close_id); 94 | ivClose.setOnClickListener(new View.OnClickListener() { 95 | @Override 96 | public void onClick(View v) { 97 | ScreenConvertor.destroyFullScreen(mVideo.getContext()); 98 | } 99 | }); 100 | vState = cv.findViewById(R.id.v_state); 101 | } 102 | v = mVideo; 103 | } 104 | container.addView(v); 105 | return v; 106 | } 107 | 108 | @Override 109 | public void destroyItem(ViewGroup container, int position, Object object) { 110 | View v = (View)object; 111 | container.removeView(v); 112 | if(position!=0) { 113 | mList.push(v); 114 | } 115 | } 116 | 117 | @Override 118 | public int getCount() { 119 | return DemoApp.mUrl.length; 120 | } 121 | 122 | @Override 123 | public boolean isViewFromObject(View view, Object object) { 124 | return view == object; 125 | } 126 | 127 | @Override 128 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 129 | 130 | } 131 | 132 | @Override 133 | public void onPageSelected(int position) { 134 | if(currentPos == 0){ 135 | ScreenConvertor.setPlaying(); 136 | } 137 | if(position == 0 && ScreenConvertor.isPlaying()){ 138 | PlayerUtils.start(); 139 | }else { 140 | PlayerUtils.pause(); 141 | } 142 | currentPos = position; 143 | if(ivClose!=null) { 144 | ivClose.setVisibility((canVisibility && position == 0) ? View.VISIBLE : View.GONE); 145 | } 146 | } 147 | 148 | @Override 149 | public void onPageScrollStateChanged(int state) { 150 | 151 | } 152 | 153 | @Override 154 | public void update(Observable observable, Object data) { 155 | if(data == null){ 156 | ivClose.setVisibility(View.GONE); 157 | }else if(data != null && currentPos == 0){ 158 | ivClose.setVisibility(View.VISIBLE); 159 | } 160 | canVisibility = (data!=null); 161 | } 162 | 163 | void changeScreen(boolean canPlay){ 164 | ScreenConvertor.setObserver(this); 165 | ScreenConvertor.setFullScreen(canPlay,mVideo); 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /demo/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 15 | 16 |