├── .gitignore ├── Demo ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ ├── jzvd.html │ ├── local_video.mp4 │ └── tiktok_data │ ├── java │ └── com │ │ └── yc │ │ └── ycvideoplayer │ │ ├── BaseActivity.java │ │ ├── BaseApplication.java │ │ ├── BuriedPointEventImpl.java │ │ ├── ConstantVideo.java │ │ ├── ImageUtil.java │ │ ├── MainActivity.java │ │ ├── ScreenDensityUtils.java │ │ ├── demo │ │ ├── DemoActivity.java │ │ ├── ExoActivity.java │ │ ├── IjkActivity.java │ │ ├── MediaActivity.java │ │ └── MediaActivity2.java │ │ ├── m3u8 │ │ └── M3u8Activity.java │ │ ├── music │ │ ├── MusicPlayerActivity.java │ │ └── PlayMusicFragment.java │ │ ├── newPlayer │ │ ├── activity │ │ │ ├── DetailActivity.java │ │ │ ├── IntentKeys.java │ │ │ ├── MultipleActivity.java │ │ │ ├── NormalActivity.java │ │ │ └── TypeActivity.java │ │ ├── ad │ │ │ ├── AdActivity.java │ │ │ └── AdControlView.java │ │ ├── clarity │ │ │ ├── ClarityActivity.java │ │ │ └── DefinitionControlView.java │ │ ├── danmu │ │ │ ├── CenteredImageSpan.java │ │ │ ├── DanmuActivity.java │ │ │ └── MyDanmakuView.java │ │ ├── list │ │ │ ├── ContinuousVideoActivity.java │ │ │ ├── OnItemChildClickListener.java │ │ │ ├── OnItemClickListener.java │ │ │ ├── PlayerMonitor.java │ │ │ ├── RecyclerView2Fragment.java │ │ │ ├── RecyclerViewAutoPlayFragment.java │ │ │ ├── RecyclerViewFragment.java │ │ │ ├── SeamlessPlayFragment.java │ │ │ ├── TestListActivity.java │ │ │ └── VideoRecyclerViewAdapter.java │ │ ├── pip │ │ │ ├── PipActivity.java │ │ │ └── PipListActivity.java │ │ ├── surface │ │ │ ├── MySurfaceView.java │ │ │ └── TestSurfaceActivity.java │ │ ├── tiktok │ │ │ ├── TikTok1Activity.java │ │ │ ├── TikTok1ListAdapter.java │ │ │ ├── TikTok1ListFragment.java │ │ │ ├── TikTok2Activity.java │ │ │ ├── TikTokListAdapter.java │ │ │ ├── TikTokListFragment.java │ │ │ ├── TikTokRenderView.java │ │ │ ├── TikTokRenderViewFactory.java │ │ │ ├── TikTokView.java │ │ │ └── Tiktok2Adapter.java │ │ └── tiny │ │ │ ├── TestFullActivity.java │ │ │ └── TinyScreenActivity.java │ │ └── oldPlayer │ │ ├── FloatPlayerView.java │ │ ├── HomeKeyWatcher.java │ │ ├── OldActivity.java │ │ ├── TestClarityActivity.java │ │ ├── TestEightVideoActivity.java │ │ ├── TestFragment.java │ │ ├── TestFragmentActivity.java │ │ ├── TestFullActivity2.java │ │ ├── TestListFragment.java │ │ ├── TestNormalActivity.java │ │ ├── TestRecyclerActivity.java │ │ ├── TestSavePosActivity.java │ │ ├── TestTinyActivity.java │ │ ├── TestWindowActivity.java │ │ ├── Video.java │ │ └── VideoAdapter.java │ └── res │ ├── anim │ ├── fragment_slide_down.xml │ └── fragment_slide_up.xml │ ├── drawable-xhdpi │ └── ic_volume.png │ ├── drawable-xxhdpi │ ├── ic_play_bar_btn_next.png │ ├── ic_play_bar_btn_pause.png │ ├── ic_play_bar_btn_play.png │ ├── ic_play_bar_playlist.png │ ├── ic_play_btn_cmt.png │ ├── ic_play_btn_cmt_pre.png │ ├── ic_play_btn_delete.png │ ├── ic_play_btn_deleted.png │ ├── ic_play_btn_loop.png │ ├── ic_play_btn_loop_pressed.png │ ├── ic_play_btn_love.png │ ├── ic_play_btn_loved.png │ ├── ic_play_btn_next.png │ ├── ic_play_btn_next_pressed.png │ ├── ic_play_btn_one.png │ ├── ic_play_btn_one_pressed.png │ ├── ic_play_btn_pause.png │ ├── ic_play_btn_pause_pressed.png │ ├── ic_play_btn_play.png │ ├── ic_play_btn_play_pressed.png │ ├── ic_play_btn_prev.png │ ├── ic_play_btn_prev_pressed.png │ ├── ic_play_btn_shuffle.png │ ├── ic_play_btn_shuffle_pressed.png │ ├── ic_play_btn_src_prs.png │ ├── ic_seek_bar_progress_btn.png │ ├── ic_seek_bar_volume_btn.png │ ├── play_icn_more.png │ └── play_page_default_bg.jpg │ ├── drawable │ ├── btn_action_bg_selector.xml │ ├── image_default.jpg │ ├── play_bar_btn_play_pause_selector.xml │ ├── play_btn_loop_selector.xml │ ├── play_btn_next_selector.xml │ ├── play_btn_one_selector.xml │ ├── play_btn_play_pause_selector.xml │ ├── play_btn_play_selector.xml │ ├── play_btn_prev_selector.xml │ ├── play_btn_shuffle_selector.xml │ ├── play_mode_level_list.xml │ ├── seek_bar_progress_style.xml │ ├── seek_bar_volume_style.xml │ └── shape_ad_bg.xml │ ├── layout │ ├── activity_ad_video.xml │ ├── activity_danmu_player.xml │ ├── activity_demo_player.xml │ ├── activity_detail_video.xml │ ├── activity_exo_player.xml │ ├── activity_full_video1.xml │ ├── activity_full_video2.xml │ ├── activity_ijk_player.xml │ ├── activity_m3u8_view.xml │ ├── activity_main.xml │ ├── activity_media_player.xml │ ├── activity_media_player2.xml │ ├── activity_multiple_play.xml │ ├── activity_music_player.xml │ ├── activity_new.xml │ ├── activity_normal_video.xml │ ├── activity_old.xml │ ├── activity_pip_video.xml │ ├── activity_test.xml │ ├── activity_test_fragment.xml │ ├── activity_test_video2.xml │ ├── activity_test_video3.xml │ ├── activity_test_window.xml │ ├── activity_tiktok2.xml │ ├── activity_video.xml │ ├── base_recycler_view.xml │ ├── fragment_play_music.xml │ ├── include_play_bar.xml │ ├── include_play_page_controller.xml │ ├── item_my_video.xml │ ├── item_tik_tok.xml │ ├── item_tiktok_list.xml │ ├── item_video.xml │ ├── layout_ad_control_view.xml │ ├── layout_definition_control_view.xml │ ├── layout_rate_item.xml │ ├── layout_rate_pop.xml │ └── layout_tiktok_controller.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml │ └── xml │ └── network_security_config.xml ├── LICENSE ├── MusicPlayer ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── yc │ │ └── music │ │ ├── config │ │ ├── MusicConstant.java │ │ ├── MusicPlayAction.java │ │ └── PlayModeEnum.java │ │ ├── inter │ │ ├── EventCallback.java │ │ └── OnPlayerEventListener.java │ │ ├── manager │ │ ├── AudioFocusManager.java │ │ ├── AudioSoundManager.java │ │ └── MediaSessionManager.java │ │ ├── model │ │ └── AudioBean.java │ │ ├── receiver │ │ ├── AudioBroadcastReceiver.java │ │ ├── AudioEarPhoneReceiver.java │ │ ├── EarphoneControlReceiver.java │ │ └── NotificationStatusBarReceiver.java │ │ ├── service │ │ └── PlayService.java │ │ ├── tool │ │ ├── BaseAppHelper.java │ │ └── QuitTimerHelper.java │ │ └── utils │ │ ├── MusicLogUtils.java │ │ ├── MusicSpUtils.java │ │ ├── NotificationHelper.java │ │ └── NotificationUtils.java │ └── res │ ├── drawable-xhdpi │ ├── default_cover.png │ ├── notify_btn_dark_next_normal.png │ ├── notify_btn_dark_pause2_normal.png │ ├── notify_btn_dark_pause_normal.png │ ├── notify_btn_dark_play_normal.png │ └── notify_btn_dark_prev_normal.png │ ├── layout │ └── notification_player.xml │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── README.md ├── VideoBarrage ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── yc │ └── videobarrage │ └── Test.java ├── VideoCache ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── yc │ └── videocache │ ├── ByteArrayCache.java │ ├── ByteArraySource.java │ ├── Cache.java │ ├── CacheListener.java │ ├── Config.java │ ├── GetRequest.java │ ├── HttpProxyCache.java │ ├── HttpProxyCacheServer.java │ ├── HttpProxyCacheServerClients.java │ ├── HttpUrlSource.java │ ├── IgnoreHostProxySelector.java │ ├── InterruptedProxyCacheException.java │ ├── Logger.java │ ├── Pinger.java │ ├── Preconditions.java │ ├── ProxyCache.java │ ├── ProxyCacheException.java │ ├── ProxyCacheUtils.java │ ├── Source.java │ ├── SourceInfo.java │ ├── StorageUtils.java │ ├── cache │ ├── PreloadManager.java │ ├── PreloadTask.java │ └── ProxyVideoCacheManager.java │ ├── file │ ├── DiskUsage.java │ ├── FileCache.java │ ├── FileNameGenerator.java │ ├── Files.java │ ├── LruDiskUsage.java │ ├── Md5FileNameGenerator.java │ ├── TotalCountLruDiskUsage.java │ ├── TotalSizeLruDiskUsage.java │ └── UnlimitedDiskUsage.java │ ├── headers │ ├── EmptyHeadersInjector.java │ └── HeaderInjector.java │ └── sourcestorage │ ├── DatabaseSourceInfoStorage.java │ ├── NoSourceInfoStorage.java │ ├── SourceInfoStorage.java │ └── SourceInfoStorageFactory.java ├── VideoGradle └── video.gradle ├── VideoKernel ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── yc │ └── kernel │ ├── factory │ └── PlayerFactory.java │ ├── impl │ ├── exo │ │ ├── ExoMediaPlayer.java │ │ ├── ExoMediaSourceHelper.java │ │ └── ExoPlayerFactory.java │ ├── ijk │ │ ├── IjkPlayerFactory.java │ │ ├── IjkVideoPlayer.java │ │ └── RawDataSourceProvider.java │ ├── media │ │ ├── AndroidMediaPlayer.java │ │ └── MediaPlayerFactory.java │ └── tx │ │ ├── TxMediaPlayer.java │ │ └── TxPlayerFactory.java │ ├── inter │ ├── AbstractVideoPlayer.java │ └── VideoPlayerListener.java │ └── utils │ ├── PlayerConstant.java │ ├── PlayerFactoryUtils.java │ └── VideoLogUtils.java ├── VideoM3u8 ├── .gitignore ├── build.gradle ├── libs │ └── commons-io-2.5.jar ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── yc │ │ └── m3u8 │ │ ├── bean │ │ ├── M3u8.java │ │ └── M3u8Ts.java │ │ ├── inter │ │ ├── BaseListener.java │ │ ├── DownLoadListener.java │ │ ├── M3U8Listener.java │ │ ├── OnDownloadListener.java │ │ └── OnM3u8InfoListener.java │ │ ├── manager │ │ ├── M3u8InfoManger.java │ │ ├── M3u8LiveManger.java │ │ └── M3u8Manger.java │ │ ├── task │ │ └── M3u8DownloadTask.java │ │ └── utils │ │ ├── M3u8FileUtils.java │ │ └── NetSpeedUtils.java │ └── res │ └── values │ └── strings.xml ├── VideoPlayer ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── yc │ │ └── video │ │ ├── bridge │ │ └── ControlWrapper.java │ │ ├── config │ │ ├── BuriedPointEvent.java │ │ ├── ConstantKeys.java │ │ ├── VideoInfoBean.java │ │ └── VideoPlayerConfig.java │ │ ├── controller │ │ ├── BaseVideoController.java │ │ ├── GestureVideoController.java │ │ ├── IGestureComponent.java │ │ ├── InterVideoController.java │ │ ├── InterViewController.java │ │ └── OrientationHelper.java │ │ ├── old │ │ ├── controller │ │ │ ├── AbsVideoPlayerController.java │ │ │ ├── IVideoController.java │ │ │ └── VideoPlayerController.java │ │ ├── dialog │ │ │ └── ChangeClarityDialog.java │ │ ├── listener │ │ │ ├── OnClarityChangedListener.java │ │ │ ├── OnPlayerStatesListener.java │ │ │ ├── OnPlayerTypeListener.java │ │ │ └── OnVideoControlListener.java │ │ ├── other │ │ │ ├── BatterReceiver.java │ │ │ ├── NetChangedReceiver.java │ │ │ └── VideoPlayerManager.java │ │ ├── player │ │ │ ├── IVideoPlayer.java │ │ │ ├── OldVideoPlayer.java │ │ │ └── VideoMediaPlayer.java │ │ └── surface │ │ │ ├── VideoSurfaceView.java │ │ │ └── VideoTextureView.java │ │ ├── player │ │ ├── AudioFocusHelper.java │ │ ├── InterVideoPlayer.java │ │ ├── OnVideoStateListener.java │ │ ├── ProgressManager.java │ │ ├── SimpleStateListener.java │ │ ├── VideoPlayer.java │ │ ├── VideoPlayerBuilder.java │ │ ├── VideoPlayerHelper.java │ │ └── VideoViewManager.java │ │ ├── surface │ │ ├── InterSurfaceView.java │ │ ├── MeasureHelper.java │ │ ├── RenderSurfaceView.java │ │ ├── RenderTextureView.java │ │ ├── SurfaceFactory.java │ │ ├── SurfaceViewFactory.java │ │ └── TextureViewFactory.java │ │ ├── tool │ │ ├── BaseToast.java │ │ ├── CountDownTimer.java │ │ ├── NetworkUtils.java │ │ ├── PlayerUtils.java │ │ ├── StatesCutoutUtils.java │ │ └── VideoException.java │ │ └── ui │ │ ├── more │ │ ├── CustomNetworkView.java │ │ └── CustomTrailersView.java │ │ ├── pip │ │ ├── CustomFloatController.java │ │ ├── CustomFloatView.java │ │ ├── FloatVideoManager.java │ │ └── FloatVideoView.java │ │ └── view │ │ ├── BasisVideoController.java │ │ ├── CustomBottomView.java │ │ ├── CustomCompleteView.java │ │ ├── CustomErrorView.java │ │ ├── CustomGestureView.java │ │ ├── CustomLiveControlView.java │ │ ├── CustomOncePlayView.java │ │ ├── CustomPrepareView.java │ │ ├── CustomTitleView.java │ │ └── InterControlView.java │ └── res │ ├── anim │ ├── anim_window_enter.xml │ └── anim_window_exit.xml │ ├── color │ └── select_change_clarity_color.xml │ ├── drawable-xhdpi │ ├── battery_10.png │ ├── battery_100.png │ ├── battery_20.png │ ├── battery_50.png │ ├── battery_80.png │ ├── battery_charging.png │ ├── battery_full.png │ ├── ic_back_close.png │ ├── ic_palyer_brightness.png │ ├── ic_palyer_share.png │ ├── ic_palyer_volume.png │ ├── ic_player_audio.png │ ├── ic_player_back.png │ ├── ic_player_center_start.png │ ├── ic_player_close.png │ ├── ic_player_dl.png │ ├── ic_player_fast_forward.png │ ├── ic_player_fast_rewind.png │ ├── ic_player_lock_close.png │ ├── ic_player_lock_open.png │ ├── ic_player_menu.png │ ├── ic_player_open.png │ ├── ic_player_pause.png │ ├── ic_player_replay.png │ ├── ic_player_share.png │ ├── ic_player_start.png │ ├── ic_player_tv.png │ ├── ic_player_volume_off.png │ ├── ic_player_volume_up.png │ ├── icon_action_refresh.png │ ├── icon_pause_center.png │ ├── icon_play_center.png │ ├── pb_loading_bg.png │ ├── player_mask_bottom.png │ └── player_mask_top.png │ ├── drawable-xxhdpi │ ├── ic_player_audio.png │ ├── ic_player_dl.png │ ├── ic_player_menu.png │ ├── ic_player_share.png │ └── ic_player_tv.png │ ├── drawable │ ├── bg_change_clarity_checked.xml │ ├── bg_change_clarity_normal.xml │ ├── bg_radius_4.xml │ ├── bg_retry.xml │ ├── pb_change.xml │ ├── pb_loading_ring.xml │ ├── progress_bar_style.xml │ ├── seek_progress.xml │ ├── seek_thumb.xml │ ├── seek_thumb_normal.xml │ ├── seek_thumb_pressed.xml │ ├── select_change_clarity.xml │ ├── selector_bot_play_button.xml │ ├── selector_full_screen_button.xml │ ├── selector_lock_button.xml │ ├── selector_play_button.xml │ ├── shape_back_bg.xml │ ├── shape_float_window_bg.xml │ ├── shape_lock_bg.xml │ ├── shape_play_bg.xml │ └── shape_status_view_bg.xml │ ├── layout │ ├── custom_toast_view.xml │ ├── custom_video_player_bottom.xml │ ├── custom_video_player_change_brightness.xml │ ├── custom_video_player_change_position.xml │ ├── custom_video_player_change_volume.xml │ ├── custom_video_player_completed.xml │ ├── custom_video_player_error.xml │ ├── custom_video_player_float.xml │ ├── custom_video_player_gesture.xml │ ├── custom_video_player_live.xml │ ├── custom_video_player_loading.xml │ ├── custom_video_player_once_live.xml │ ├── custom_video_player_prepare.xml │ ├── custom_video_player_standard.xml │ ├── custom_video_player_top.xml │ ├── custom_view_guide.xml │ ├── old_video_clarity.xml │ ├── old_video_player.xml │ ├── old_video_player_bottom.xml │ ├── old_video_player_completed.xml │ ├── old_video_player_error.xml │ ├── old_video_player_line.xml │ ├── old_video_player_top.xml │ └── old_view_window_dialog.xml │ └── values │ ├── attrs.xml │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── VideoRecorder ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── yc │ └── videorecorder │ └── Test.java ├── VideoScreen ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── yc │ └── videoscreen │ └── Test.java ├── VideoSqlLite ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro ├── read │ ├── 01.内存缓存之LruCache.md │ ├── 02.磁盘缓存之DiskLruCache.md │ ├── 03.内存磁盘二级缓存.md │ ├── 04.LruCache源码分析.md │ └── 05.DiskLruCache源码分析.md └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── yc │ └── videosqllite │ ├── TestDemo.java │ ├── cache │ ├── InterCache.java │ ├── SystemLruCache.java │ ├── VideoLruCache.java │ └── VideoMapCache.java │ ├── disk │ ├── DiskCacheWriteLocker.java │ ├── DiskFileUtils.java │ ├── DiskLruCache.java │ ├── DiskLruCacheFactory.java │ ├── DiskLruCacheWrapper.java │ ├── DiskUtils.java │ ├── ExternalDiskCacheFactory.java │ ├── InterDiskCache.java │ ├── InterDiskFactory.java │ ├── InternalDiskCacheFactory.java │ ├── SqlLiteCache.java │ ├── StrictLineReader.java │ └── Synthetic.java │ ├── manager │ ├── CacheConfig.java │ └── LocationManager.java │ ├── model │ ├── SafeKeyGenerator.java │ └── VideoLocation.java │ └── utils │ ├── CacheLogUtils.java │ └── VideoMd5Utils.java ├── VideoTool ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── yc │ │ └── videotool │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── yc │ │ └── videotool │ │ └── Tool.java │ └── test │ └── java │ └── com │ └── yc │ └── videotool │ └── ExampleUnitTest.java ├── VideoView ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── yc │ └── videoview │ ├── FloatLifecycle.java │ ├── FloatPhone.java │ ├── FloatToast.java │ ├── FloatView.java │ ├── FloatWindow.java │ ├── IFloatWindow.java │ ├── IFloatWindowImpl.java │ ├── LifecycleListener.java │ ├── MoveType.java │ ├── PermissionActivity.java │ ├── SmallWindowTouch.java │ ├── WindowScreen.java │ └── WindowUtil.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── image ├── 101602551518_.pic.jpg ├── 111602569651_.pic.jpg ├── 11602551140_.pic_hd.jpg ├── 121602569652_.pic.jpg ├── 131602569653_.pic.jpg ├── 141602569654_.pic.jpg ├── 151602569655_.pic.jpg ├── 161602569656_.pic.jpg ├── 21602551141_.pic_hd.jpg ├── 31602551142_.pic_hd.jpg ├── 41602551143_.pic_hd.jpg ├── 51602551144_.pic_hd.jpg ├── 61602551145_.pic_hd.jpg ├── 71602551146_.pic_hd.jpg ├── 81602551147_.pic_hd.jpg ├── 91602551148_.pic_hd.jpg ├── 播放器框架总图.jpg ├── 直播服务架构图.png ├── 视频播放器UI.png ├── 视频播放器内核.png ├── 视频播放器内核架构图.jpg ├── 视频播放器层级示例图.jpg ├── 视频播放器库整体介绍.png └── 视频直播流程图.png ├── read ├── 01.视频播放器介绍文档.md ├── 02.视频播放器整体结构.md ├── 03.视频播放器Api说明.md ├── 04.视频播放器封装思路.md ├── 05.播放器内核切换封装.md ├── 06.播放器UI抽取封装.md ├── 07.MediaPlayer详细介绍.md ├── 08.视频播放器优化处理.md ├── 09.视频深度优化处理.md ├── 10.视频全局悬浮窗播放.md ├── 11.视频播放器音频焦点抢占.md ├── 12.视频边播边缓存分析.md ├── 13.视频播放器如何选择.md ├── 14.视频播放器简单案例.md ├── 15.视频播放器流程分析.md ├── 16.视频播放器列表播放.md ├── 17.基础播放器问题记录.md ├── 18.Exo播放器问题记录.md ├── 19.Ijk播放器问题记录.md ├── 20.视频播放器版本更新文档.md ├── 21.视频播放器后期需求.md ├── 22.视频基础概念术语.md ├── 23.视频VideoView学习.md ├── 24.1SurfaceView深入学习.md ├── 24.2SurfaceView源码分析.md ├── 25.TextureView深入学习.md ├── 26.视频编码和解码学习.md ├── 27.视频加密和解密处理.md ├── 28.视频录制和编辑学习.md ├── 29.视频播放器埋点监听.md ├── 30.视频播放器使用设计模式.md ├── 31.音频播放器通用框架.md ├── 32.音频焦点抢占问题.md ├── 34.音频播放锁屏分析.md ├── 35.耳机控制音视频音量.md ├── 40.完整音频播放器分析.md ├── 42.音视频本地文件扫描.md ├── 43.音视频编解码操作.md ├── 43.音频基础知识点.md ├── 45.音视频加密和解密.md ├── 48.音视频问题考点.md ├── 49.参考项目和博客说明.md ├── 50.版本更新说明文档.md ├── 51.直播基础知识点介绍.md ├── 52.直播推流端分析.md └── 53.直播播放端分析.md └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | 16 | 17 | 18 | 19 | # Built application files 20 | *.apk 21 | *.ap_ 22 | 23 | # Files for the ART/Dalvik VM 24 | *.dex 25 | 26 | # Java class files 27 | *.class 28 | 29 | # Generated files 30 | bin/ 31 | gen/ 32 | out/ 33 | 34 | # Gradle files 35 | .gradle/ 36 | build/ 37 | 38 | # Local configuration file (sdk path, etc) 39 | local.properties 40 | 41 | # Proguard folder generated by Eclipse 42 | proguard/ 43 | 44 | # Log Files 45 | *.log 46 | 47 | # Android Studio Navigation editor temp files 48 | .navigation/ 49 | 50 | # Android Studio captures folder 51 | captures/ 52 | 53 | # Intellij 54 | *.iml 55 | .idea/workspace.xml 56 | .idea/tasks.xml 57 | .idea/gradle.xml 58 | .idea/dictionaries 59 | .idea/libraries 60 | 61 | # Keystore files 62 | *.jks 63 | 64 | # External native build folder generated in Android Studio 2.2 and later 65 | .externalNativeBuild 66 | 67 | # Google Services (e.g. APIs or Firebase) 68 | google-services.json 69 | 70 | # Freeline 71 | freeline.py 72 | freeline/ 73 | freeline_project_description.json 74 | .idea/ 75 | 76 | 77 | -------------------------------------------------------------------------------- /Demo/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Demo/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | 23 | 24 | #ijkplayer 25 | -keep class tv.danmaku.ijk.media.player.** {*;} 26 | -keep class tv.danmaku.ijk.media.player.IjkMediaPlayer{*;} 27 | -keep class tv.danmaku.ijk.media.player.ffmpeg.FFmpegApi{*;} 28 | 29 | 30 | # 视频播放器 31 | # 视频内核 32 | -keep class com.yc.kernel.**{*;} 33 | # 视频播放器 34 | -keep class com.yc.video.**{*;} 35 | # 视频缓存 36 | -keep class com.yc.videocache.**{*;} 37 | # 视频悬浮view 38 | -keep class com.yc.videoview.**{*;} 39 | # 视频位置记录 40 | -keep class com.yc.videosqllite.**{*;} 41 | # 视频m3u8分片下载和合成 42 | -keep class com.yc.m3u8.**{*;} 43 | 44 | -------------------------------------------------------------------------------- /Demo/src/main/assets/jzvd.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |10 | * @author yangchong 11 | * blog : https://github.com/yangchong211 12 | * time : 2018/11/9 13 | * desc : 此接口使用方法 14 | * revise: 1.继承{@link AbstractVideoPlayer}扩展自己的播放器。 15 | * 2.继承此接口并实现{@link #createPlayer(Context)},返回步骤1中的播放器。 16 | *17 | */ 18 | public abstract class PlayerFactory
9 | * @author yangchong 10 | * blog : https://github.com/yangchong211 11 | * time : 2018/11/9 12 | * desc : exo视频播放器Factory 13 | * revise: 抽象工厂具体实现类 14 | *15 | */ 16 | public class ExoPlayerFactory extends PlayerFactory
23 | * @author yangchong 24 | * blog : https://github.com/yangchong211 25 | * time : 2018/11/9 26 | * desc : ijk视频播放器Factory 27 | * revise: 抽象工厂具体实现类 28 | *29 | */ 30 | public class IjkPlayerFactory extends PlayerFactory
25 | * @author yangchong 26 | * blog : https://github.com/yangchong211 27 | * time : 2018/11/9 28 | * desc : 不推荐,系统的MediaPlayer兼容性较差,建议使用IjkPlayer或者ExoPlayer 29 | * revise: 抽象工厂具体实现类 30 | *31 | */ 32 | public class MediaPlayerFactory extends PlayerFactory
26 | * @author yangchong 27 | * blog : https://github.com/yangchong211 28 | * time : 2018/11/9 29 | * desc : tx视频播放器Factory 30 | * revise: 31 | *32 | */ 33 | public class TxPlayerFactory extends PlayerFactory
8 | * @author yangchong 9 | * blog : https://github.com/yangchong211 10 | * time : 2017/10/21 11 | * desc : 常量类 12 | * revise: 13 | *14 | */ 15 | public final class PlayerConstant { 16 | 17 | 18 | /** 19 | * 视频传入url为空 20 | */ 21 | public static final int MEDIA_INFO_URL_NULL = -1; 22 | 23 | /** 24 | * 开始渲染视频画面 25 | */ 26 | public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; 27 | 28 | /** 29 | * 缓冲开始 30 | */ 31 | public static final int MEDIA_INFO_BUFFERING_START = 701; 32 | 33 | /** 34 | * 缓冲结束 35 | */ 36 | public static final int MEDIA_INFO_BUFFERING_END = 702; 37 | 38 | /** 39 | * 视频旋转信息 40 | */ 41 | public static final int MEDIA_INFO_VIDEO_ROTATION_CHANGED = 10001; 42 | 43 | /** 44 | * 通过注解限定类型 45 | * TYPE_IJK IjkPlayer,基于IjkPlayer封装播放器 46 | * TYPE_NATIVE MediaPlayer,基于原生自带的播放器控件 47 | * TYPE_EXO 基于谷歌视频播放器 48 | * TYPE_RTC 基于RTC视频播放器 49 | */ 50 | @Retention(RetentionPolicy.SOURCE) 51 | public @interface PlayerType { 52 | int TYPE_IJK = 1; 53 | int TYPE_NATIVE = 2; 54 | int TYPE_EXO = 3; 55 | int TYPE_RTC = 4; 56 | } 57 | 58 | @Retention(RetentionPolicy.SOURCE) 59 | public @interface ErrorType { 60 | //错误的链接 61 | int TYPE_SOURCE = 1; 62 | //解析异常 63 | int TYPE_PARSE = 2; 64 | //其他异常 65 | int TYPE_UNEXPECTED = 3; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /VideoM3u8/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /VideoM3u8/libs/commons-io-2.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yangchong211/YCVideoPlayer/9d59f95353f81dae9912f0141c00f7944fad944c/VideoM3u8/libs/commons-io-2.5.jar -------------------------------------------------------------------------------- /VideoM3u8/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 F:\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 | -------------------------------------------------------------------------------- /VideoM3u8/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |
6 | * @author yangchong 7 | * blog : https://github.com/yangchong211 8 | * time : 2018/11/9 9 | * desc : 监听基类 10 | * revise: 11 | *12 | */ 13 | public interface BaseListener { 14 | /** 15 | * 开始的时候回调 16 | */ 17 | void onStart(); 18 | 19 | /** 20 | * 错误的时候回调 21 | * @param errorMsg 错误异常 22 | */ 23 | void onError(Throwable errorMsg); 24 | } 25 | -------------------------------------------------------------------------------- /VideoM3u8/src/main/java/com/yc/m3u8/inter/DownLoadListener.java: -------------------------------------------------------------------------------- 1 | package com.yc.m3u8.inter; 2 | 3 | 4 | 5 | /** 6 | *
7 | * @author yangchong 8 | * blog : https://github.com/yangchong211 9 | * time : 2018/11/9 10 | * desc : 加载监听器 11 | * revise: 12 | *13 | */ 14 | public interface DownLoadListener { 15 | /** 16 | * 开始的时候回调 17 | */ 18 | void onStart(); 19 | 20 | /** 21 | * 错误的时候回调 22 | * 23 | * @param errorMsg 24 | */ 25 | void onError(Throwable errorMsg); 26 | 27 | /** 28 | * 下载完成的时候回调 29 | */ 30 | void onCompleted(); 31 | } 32 | -------------------------------------------------------------------------------- /VideoM3u8/src/main/java/com/yc/m3u8/inter/M3U8Listener.java: -------------------------------------------------------------------------------- 1 | package com.yc.m3u8.inter; 2 | 3 | import com.yc.m3u8.bean.M3u8; 4 | 5 | /** 6 | * @deprecated v2版本过时了,请用 7 | * 监听器 8 | * Created by HDL on 2017/7/25. 9 | */ 10 | 11 | public abstract class M3U8Listener implements DownLoadListener { 12 | public void onM3U8Info(M3u8 m3U8) { 13 | } 14 | 15 | public void onDownloadingProgress(int total, int progress) { 16 | } 17 | 18 | /** 19 | * 当获取到单个文件大小的时候回调 20 | * 21 | * @param fileSize 单个文件大小 22 | */ 23 | public void onLoadFileSizeForItem(long fileSize) { 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /VideoM3u8/src/main/java/com/yc/m3u8/inter/OnDownloadListener.java: -------------------------------------------------------------------------------- 1 | package com.yc.m3u8.inter; 2 | 3 | import com.yc.m3u8.inter.BaseListener; 4 | 5 | 6 | /** 7 | *
8 | * @author yangchong 9 | * blog : https://github.com/yangchong211 10 | * time : 2018/11/9 11 | * desc : 下载监听 12 | * revise: 13 | *14 | */ 15 | public interface OnDownloadListener extends BaseListener { 16 | /** 17 | * 下载m3u8文件. 18 | * 注意:这个方法是异步的(子线程中执行),所以不能在此方法中回调,其他方法为主线程中回调 19 | * 20 | * @param itemFileSize 单个文件的大小 21 | * @param totalTs ts总数 22 | * @param curTs 当前下载完成的ts个数 23 | */ 24 | void onDownloading(long itemFileSize, int totalTs, int curTs); 25 | 26 | /** 27 | * 下载成功 28 | */ 29 | void onSuccess(); 30 | 31 | /** 32 | * 当前已经下载的文件大小 33 | * 34 | * @param curLength 35 | */ 36 | void onProgress(long curLength); 37 | } 38 | -------------------------------------------------------------------------------- /VideoM3u8/src/main/java/com/yc/m3u8/inter/OnM3u8InfoListener.java: -------------------------------------------------------------------------------- 1 | package com.yc.m3u8.inter; 2 | 3 | import com.yc.m3u8.bean.M3u8; 4 | 5 | /** 6 | *
7 | * @author yangchong 8 | * blog : https://github.com/yangchong211 9 | * time : 2018/11/9 10 | * desc : 获取M3U8信息 11 | * revise: 12 | *13 | */ 14 | public interface OnM3u8InfoListener extends BaseListener { 15 | 16 | /** 17 | * 获取成功的时候回调 18 | */ 19 | void onSuccess(M3u8 m3U8); 20 | } 21 | -------------------------------------------------------------------------------- /VideoM3u8/src/main/java/com/yc/m3u8/utils/NetSpeedUtils.java: -------------------------------------------------------------------------------- 1 | package com.yc.m3u8.utils; 2 | 3 | /** 4 | * 网速工具 5 | * Created by HDL on 2017/8/14. 6 | */ 7 | 8 | public class NetSpeedUtils { 9 | private static NetSpeedUtils mNetSpeedUtils; 10 | 11 | private NetSpeedUtils() { 12 | } 13 | 14 | public static NetSpeedUtils getInstance() { 15 | synchronized (NetSpeedUtils.class) { 16 | if (mNetSpeedUtils == null) { 17 | mNetSpeedUtils = new NetSpeedUtils(); 18 | } 19 | } 20 | return mNetSpeedUtils; 21 | } 22 | 23 | //字节大小,K,M,G 24 | public static final long KB = 1024; 25 | public static final long MB = KB * 1024; 26 | public static final long GB = MB * 1024; 27 | 28 | /** 29 | * 文件字节大小显示成M,G和K 30 | * 31 | * @param size 32 | * @return 33 | */ 34 | public String displayFileSize(long size) { 35 | if (size >= GB) { 36 | return String.format("%.1f GB", (float) size / GB); 37 | } else if (size >= MB) { 38 | float value = (float) size / MB; 39 | return String.format(value > 100 ? "%.0f MB" : "%.1f MB", value); 40 | } else if (size >= KB) { 41 | float value = (float) size / KB; 42 | return String.format(value > 100 ? "%.0f KB" : "%.1f KB", value); 43 | } else { 44 | return String.format("%d B", size); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /VideoM3u8/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 |
21 | * @author yangchong 22 | * blog : https://github.com/yangchong211 23 | * time : 2017/11/21 24 | * desc : 清晰度监听接口 25 | * revise: 26 | *27 | */ 28 | @Deprecated 29 | public interface OnClarityChangedListener { 30 | 31 | /** 32 | * 切换清晰度后回调 33 | * 34 | * @param clarityIndex 切换到的清晰度的索引值 35 | */ 36 | void onClarityChanged(int clarityIndex); 37 | 38 | /** 39 | * 清晰度没有切换,比如点击了空白位置,或者点击的是之前的清晰度 40 | */ 41 | void onClarityNotChanged(); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /VideoPlayer/src/main/java/com/yc/video/old/listener/OnPlayerStatesListener.java: -------------------------------------------------------------------------------- 1 | package com.yc.video.old.listener; 2 | 3 | import com.yc.video.config.ConstantKeys; 4 | 5 | /** 6 | *
7 | * @author yangchong 8 | * blog : https://github.com/yangchong211 9 | * time : 2018/3/9 10 | * desc : 视频播放状态抽象接口 11 | * revise: 12 | *13 | */ 14 | @Deprecated 15 | public interface OnPlayerStatesListener { 16 | 17 | /** 18 | * 视频播放状态监听,暴露给外部开发者调用 19 | * int COMPLETED = 101; 播放完成 20 | * int PLAYING = 102; 正在播放 21 | * int PAUSE = 103; 暂停状态 22 | * int BACK_CLICK = 104; 用户点击back。当视频退出全屏或者退出小窗口后,再次点击返回键,让用户自己处理返回键事件的逻辑 23 | * @param states 状态 24 | */ 25 | void onPlayerStates(@ConstantKeys.PlayerStatesType int states); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /VideoPlayer/src/main/java/com/yc/video/old/listener/OnPlayerTypeListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 yangchong211(github.com/yangchong211) 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 | package com.yc.video.old.listener; 17 | 18 | 19 | import com.yc.video.config.ConstantKeys; 20 | 21 | /** 22 | *
23 | * @author yangchong 24 | * blog : https://github.com/yangchong211 25 | * time : 2018/3/9 26 | * desc : 视频播放模式监听 27 | * revise: 28 | *29 | */ 30 | @Deprecated 31 | public interface OnPlayerTypeListener { 32 | 33 | /** 34 | * 视频播放模式监听 35 | * int FULL_SCREEN = 101; 切换到全屏播放监听 36 | * int TINY_WINDOW = 102; 切换到小窗口播放监听 37 | * int NORMAL = 103; 切换到正常播放监听 38 | * @param type 类型 39 | */ 40 | void onPlayerPattern(@ConstantKeys.PlayMode int type); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /VideoPlayer/src/main/java/com/yc/video/old/listener/OnVideoControlListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 yangchong211(github.com/yangchong211) 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 | package com.yc.video.old.listener; 17 | 18 | 19 | import com.yc.video.config.ConstantKeys; 20 | 21 | /** 22 | *
23 | * @author yangchong 24 | * blog : https://github.com/yangchong211 25 | * time : 2017/11/9 26 | * desc : 视频顶部点击事件 27 | * revise: 28 | *29 | */ 30 | @Deprecated 31 | public interface OnVideoControlListener { 32 | 33 | /** 34 | * 视频顶部点击事件【下载,切换音频,分享等】 35 | * @param type 类型 36 | * 在竖屏模式下 37 | * 1.DOWNLOAD,下载 38 | * 2.AUDIO,切换音频 39 | * 3.SHARE,分享 40 | * 4.MENU,菜单 41 | * 42 | * 在横屏模式下 43 | * 5.TV,tv映射 44 | * 6.HOR_AUDIO,音频 45 | */ 46 | void onVideoControlClick(@ConstantKeys.VideoControlType int type); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /VideoPlayer/src/main/java/com/yc/video/player/ProgressManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 yangchong211(github.com/yangchong211) 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 | package com.yc.video.player; 17 | 18 | /** 19 | * 播放进度管理器,继承此接口实现自己的进度管理器。 20 | */ 21 | public abstract class ProgressManager { 22 | 23 | /** 24 | * 此方法用于实现保存进度的逻辑 25 | * @param url 播放地址 26 | * @param progress 播放进度 27 | */ 28 | public abstract void saveProgress(String url, long progress); 29 | 30 | /** 31 | * 此方法用于实现获取保存的进度的逻辑 32 | * @param url 播放地址 33 | * @return 保存的播放进度 34 | */ 35 | public abstract long getSavedProgress(String url); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /VideoPlayer/src/main/java/com/yc/video/surface/SurfaceFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 yangchong211(github.com/yangchong211) 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 | package com.yc.video.surface; 17 | 18 | import android.content.Context; 19 | 20 | /** 21 | *
22 | * @author yangchong 23 | * blog : https://github.com/yangchong211 24 | * time : 2018/11/9 25 | * desc : 扩展自己的渲染View 26 | * revise: 可以使用TextureView,可参考{@link RenderTextureView}和{@link TextureViewFactory}的实现。 27 | *28 | */ 29 | public abstract class SurfaceFactory { 30 | 31 | public abstract InterSurfaceView createRenderView(Context context); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /VideoPlayer/src/main/java/com/yc/video/surface/SurfaceViewFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 yangchong211(github.com/yangchong211) 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 | package com.yc.video.surface; 17 | 18 | import android.content.Context; 19 | 20 | /** 21 | *
22 | * @author yangchong 23 | * blog : https://github.com/yangchong211 24 | * time : 2018/11/9 25 | * desc : 实现类 26 | * revise: 27 | *28 | */ 29 | public class SurfaceViewFactory extends SurfaceFactory { 30 | 31 | public static SurfaceViewFactory create() { 32 | return new SurfaceViewFactory(); 33 | } 34 | 35 | @Override 36 | public InterSurfaceView createRenderView(Context context) { 37 | //创建SurfaceView 38 | return new RenderSurfaceView(context); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /VideoPlayer/src/main/java/com/yc/video/surface/TextureViewFactory.java: -------------------------------------------------------------------------------- 1 | package com.yc.video.surface; 2 | 3 | import android.content.Context; 4 | 5 | /** 6 | *
7 | * @author yangchong 8 | * blog : https://github.com/yangchong211 9 | * time : 2018/11/9 10 | * desc : 实现类 11 | * revise: 12 | *13 | */ 14 | public class TextureViewFactory extends SurfaceFactory { 15 | 16 | public static TextureViewFactory create() { 17 | return new TextureViewFactory(); 18 | } 19 | 20 | @Override 21 | public InterSurfaceView createRenderView(Context context) { 22 | //创建TextureView 23 | return new RenderTextureView(context); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /VideoPlayer/src/main/java/com/yc/video/tool/VideoException.java: -------------------------------------------------------------------------------- 1 | package com.yc.video.tool; 2 | 3 | /** 4 | *
5 | * @author yangchong 6 | * blog : https://github.com/yangchong211 7 | * time : 2018/11/9 8 | * desc : 播放器异常 9 | * revise: 抛出异常并且供开发者快捷查询异常定位代码 10 | *11 | */ 12 | public class VideoException extends RuntimeException { 13 | 14 | private int mCode = 0; 15 | 16 | public VideoException(int code, String msg) { 17 | super(msg); 18 | mCode = code; 19 | } 20 | 21 | @Deprecated 22 | public VideoException(String msg) { 23 | super(msg); 24 | } 25 | 26 | public VideoException(Throwable throwable) { 27 | super(throwable); 28 | if (throwable instanceof VideoException) { 29 | mCode = ((VideoException) throwable).getCode(); 30 | } 31 | } 32 | 33 | public int getCode() { 34 | return mCode; 35 | } 36 | 37 | public String getMsg() { 38 | return getMessage(); 39 | } 40 | 41 | //自定义RenderView不能设置为null 42 | public static final int CODE_NOT_RENDER_FACTORY = 19; 43 | //PlayerFactory不能设置为null 44 | public static final int CODE_NOT_PLAYER_FACTORY = 20; 45 | //VideoPlayer,需要在start播放前给设置控制器Controller 46 | public static final int CODE_NOT_SET_CONTROLLER = 21; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /VideoPlayer/src/main/res/anim/anim_window_enter.xml: -------------------------------------------------------------------------------- 1 | 2 |
10 | * @author yangchong 11 | * email : yangchong211@163.com 12 | * time : 2020/6/16 13 | * desc : 使用代码案例 14 | * revise: 15 | *16 | */ 17 | public class TestDemo { 18 | 19 | private void init(Context context){ 20 | CacheConfig cacheConfig = new CacheConfig(); 21 | //设置配置是生效 22 | cacheConfig.setIsEffective(true); 23 | /* 24 | * 0,表示内存缓存 25 | * 1,表示磁盘缓存 26 | * 2,表示内存缓存+磁盘缓存 27 | */ 28 | cacheConfig.setType(2); 29 | //设置上下文 30 | cacheConfig.setContext(context); 31 | //设置最大缓存 32 | cacheConfig.setCacheMax(1000); 33 | //设置是否打印log 34 | cacheConfig.setLog(false); 35 | //初始化 36 | LocationManager.getInstance().init(cacheConfig); 37 | 38 | 39 | //保存播放位置 40 | // VideoLocation location = new VideoLocation(url, currentPosition, duration); 41 | // LocationManager.getInstance().put(url,location); 42 | 43 | //获取播放位置 44 | // final long location = LocationManager.getInstance().get(url); 45 | 46 | //清除所有位置 47 | // LocationManager.getInstance().clearAll(); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /VideoSqlLite/src/main/java/com/yc/videosqllite/disk/InterDiskCache.java: -------------------------------------------------------------------------------- 1 | package com.yc.videosqllite.disk; 2 | 3 | /** 4 | *
5 | * @author yangchong 6 | * email : yangchong211@163.com 7 | * time : 2020/8/6 8 | * desc : 磁盘缓存接口 9 | * revise: 10 | *11 | */ 12 | public interface InterDiskCache { 13 | 14 | String get(String key); 15 | 16 | void put(String key, String data); 17 | 18 | boolean remove(String key); 19 | 20 | boolean containsKey(String key); 21 | 22 | void clear(); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /VideoSqlLite/src/main/java/com/yc/videosqllite/disk/InterDiskFactory.java: -------------------------------------------------------------------------------- 1 | package com.yc.videosqllite.disk; 2 | 3 | 4 | interface InterDiskFactory { 5 | 6 | /** 250 MB of cache. */ 7 | int DEFAULT_DISK_CACHE_SIZE = 250 * 1024 * 1024; 8 | String DEFAULT_DISK_CACHE_DIR = "disk"; 9 | 10 | InterDiskCache build(); 11 | } 12 | -------------------------------------------------------------------------------- /VideoSqlLite/src/main/java/com/yc/videosqllite/disk/InternalDiskCacheFactory.java: -------------------------------------------------------------------------------- 1 | package com.yc.videosqllite.disk; 2 | 3 | import android.content.Context; 4 | 5 | import java.io.File; 6 | 7 | /** 8 | *
9 | * @author yangchong 10 | * email : yangchong211@163.com 11 | * time : 2020/8/6 12 | * desc : 创建一个基于内部的磁盘缓存磁盘缓存目录 13 | * revise: 14 | *15 | */ 16 | public final class InternalDiskCacheFactory extends DiskLruCacheFactory { 17 | 18 | public InternalDiskCacheFactory(Context context) { 19 | this(context, InterDiskFactory.DEFAULT_DISK_CACHE_DIR, 20 | InterDiskFactory.DEFAULT_DISK_CACHE_SIZE); 21 | } 22 | 23 | public InternalDiskCacheFactory(Context context, long diskCacheSize) { 24 | this(context, InterDiskFactory.DEFAULT_DISK_CACHE_DIR, diskCacheSize); 25 | } 26 | 27 | public InternalDiskCacheFactory(final Context context, final String diskCacheName, 28 | long diskCacheSize) { 29 | super(new CacheDirectoryGetter() { 30 | @Override 31 | public File getCacheDirectory() { 32 | File cacheDirectory = context.getCacheDir(); 33 | if (cacheDirectory == null) { 34 | return null; 35 | } 36 | if (diskCacheName != null) { 37 | return new File(cacheDirectory, diskCacheName); 38 | } 39 | return cacheDirectory; 40 | } 41 | }, diskCacheSize); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /VideoSqlLite/src/main/java/com/yc/videosqllite/disk/Synthetic.java: -------------------------------------------------------------------------------- 1 | package com.yc.videosqllite.disk; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Indicates that target's visibility can be relaxed to avoid synthetic methods. 10 | */ 11 | @Retention(RetentionPolicy.SOURCE) 12 | @Target({ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.TYPE}) 13 | public @interface Synthetic { 14 | } 15 | -------------------------------------------------------------------------------- /VideoTool/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /VideoTool/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 29 5 | buildToolsVersion "29.0.3" 6 | 7 | defaultConfig { 8 | minSdkVersion 16 9 | targetSdkVersion 29 10 | versionCode 1 11 | versionName "1.0" 12 | 13 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 14 | consumerProguardFiles 'consumer-rules.pro' 15 | } 16 | 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | 24 | } 25 | 26 | dependencies { 27 | implementation fileTree(dir: 'libs', include: ['*.jar']) 28 | 29 | implementation 'androidx.appcompat:appcompat:1.2.0' 30 | testImplementation 'junit:junit:4.12' 31 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 32 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 33 | } 34 | -------------------------------------------------------------------------------- /VideoTool/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yangchong211/YCVideoPlayer/9d59f95353f81dae9912f0141c00f7944fad944c/VideoTool/consumer-rules.pro -------------------------------------------------------------------------------- /VideoTool/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /VideoTool/src/androidTest/java/com/yc/videotool/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.yc.videotool; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented test, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under test. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | 25 | assertEquals("com.yc.videotool.test", appContext.getPackageName()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /VideoTool/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |