├── .gitignore
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── android
│ │ └── player
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ ├── test.mp4
│ │ ├── tiktok
│ │ └── videos
│ ├── java
│ │ └── com
│ │ │ └── android
│ │ │ └── player
│ │ │ ├── App.java
│ │ │ ├── base
│ │ │ ├── BaseActivity.java
│ │ │ ├── BaseContract.java
│ │ │ ├── BaseFragment.java
│ │ │ ├── BasePresenter.java
│ │ │ └── adapter
│ │ │ │ ├── BaseAdapter.java
│ │ │ │ ├── BaseMultiItemAdapter.java
│ │ │ │ ├── BaseNoimalAdapter.java
│ │ │ │ ├── interfaces
│ │ │ │ ├── MultiItemEntity.java
│ │ │ │ ├── OnItemChildClickListener.java
│ │ │ │ ├── OnItemClickListener.java
│ │ │ │ └── OnLoadMorePresenter.java
│ │ │ │ └── widget
│ │ │ │ ├── BaseViewHolder.java
│ │ │ │ └── OnLoadMoreListener.java
│ │ │ ├── bean
│ │ │ ├── Menu.java
│ │ │ ├── Params.java
│ │ │ └── Version.java
│ │ │ ├── controller
│ │ │ ├── DanmuWidgetView.java
│ │ │ └── LiveControllerControl.java
│ │ │ ├── danmu
│ │ │ ├── DanmuParser.java
│ │ │ └── DanmuPaserView.java
│ │ │ ├── manager
│ │ │ └── PlayerManager.java
│ │ │ ├── net
│ │ │ ├── BaseEngin.java
│ │ │ ├── OkHttpUtils.java
│ │ │ ├── OnDownloadListener.java
│ │ │ └── OnResultCallBack.java
│ │ │ ├── pager
│ │ │ ├── activity
│ │ │ │ └── PagerPlayerActivity.java
│ │ │ ├── adapter
│ │ │ │ ├── PagerPlayerAdapter.java
│ │ │ │ └── VideoListAdapter.java
│ │ │ ├── base
│ │ │ │ └── BaseViewPager.java
│ │ │ ├── bean
│ │ │ │ └── VideoBean.java
│ │ │ ├── controller
│ │ │ │ └── ShortControllerControl.java
│ │ │ ├── fragment
│ │ │ │ ├── PagerPlayerFragment.java
│ │ │ │ └── VideoListFragment.java
│ │ │ ├── interfaces
│ │ │ │ ├── IViewPager.java
│ │ │ │ └── OnViewPagerListener.java
│ │ │ └── widget
│ │ │ │ ├── ControlLiveView.java
│ │ │ │ ├── MarqueeTextView.java
│ │ │ │ ├── MusicDiscView.java
│ │ │ │ ├── PagerVideoController.java
│ │ │ │ └── ViewPagerLayoutManager.java
│ │ │ ├── render
│ │ │ └── CoustomSurfaceView.java
│ │ │ ├── ui
│ │ │ ├── activity
│ │ │ │ ├── AssetsPlayerActivity.java
│ │ │ │ ├── DanmuPlayerActivity.java
│ │ │ │ ├── LivePlayerActivity.java
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── PadActivity.java
│ │ │ │ ├── PerviewPlayerActivity.java
│ │ │ │ ├── PiPPlayerActivity.java
│ │ │ │ ├── VideoCacheActivity.java
│ │ │ │ ├── VideoListPlayerActivity.java
│ │ │ │ ├── VideoPlayerActivity.java
│ │ │ │ ├── VideosPlayerActivity.java
│ │ │ │ ├── WindowGlobalPlayerActivity.java
│ │ │ │ ├── WindowPermissionActivity.java
│ │ │ │ └── WindowPlayerActivity.java
│ │ │ ├── adapter
│ │ │ │ └── MainMenuAdapter.java
│ │ │ └── widget
│ │ │ │ ├── BoldTextView.java
│ │ │ │ ├── CorePlayerView.java
│ │ │ │ ├── GlideCircleTransform.java
│ │ │ │ ├── ListPlayerHolder.java
│ │ │ │ ├── LoadingView.java
│ │ │ │ ├── ProjectDialog.java
│ │ │ │ └── TitleView.java
│ │ │ ├── utils
│ │ │ ├── DataFactory.java
│ │ │ ├── DateParseUtil.java
│ │ │ ├── GlideModel.java
│ │ │ ├── Logger.java
│ │ │ ├── ScreenUtils.java
│ │ │ ├── SharedPreferencesUtil.java
│ │ │ ├── StatusUtils.java
│ │ │ └── WindowPermission.java
│ │ │ └── video
│ │ │ ├── adapter
│ │ │ ├── ListDetailsAdapter.java
│ │ │ └── ListPlayerAdapter.java
│ │ │ ├── bean
│ │ │ ├── OpenEyesAuthor.java
│ │ │ ├── OpenEyesContent.java
│ │ │ ├── OpenEyesIndexInfo.java
│ │ │ ├── OpenEyesIndexItemBean.java
│ │ │ └── VideoParams.java
│ │ │ ├── contract
│ │ │ └── VideoListContract.java
│ │ │ ├── listener
│ │ │ └── OnMenuActionListener.java
│ │ │ ├── model
│ │ │ └── IndexVideoEngin.java
│ │ │ ├── presenter
│ │ │ └── VideoListPersenter.java
│ │ │ └── ui
│ │ │ ├── activity
│ │ │ ├── PagerListActivity.java
│ │ │ └── VideoDetailsActivity.java
│ │ │ ├── fragment
│ │ │ ├── ListAutoPlayerChangeFragment.java
│ │ │ ├── ListPlayerChangedFragment.java
│ │ │ └── ListPlayerFragment.java
│ │ │ └── widget
│ │ │ ├── ControPerviewView.java
│ │ │ ├── PlayerMenuDialog.java
│ │ │ ├── PlayerMenuView.java
│ │ │ ├── PlayerNewbieView.java
│ │ │ ├── RoundCornerImageView.java
│ │ │ └── SdkDefaultFuncation.java
│ └── res
│ │ ├── anim
│ │ ├── bottom_menu_enter.xml
│ │ └── bottom_menu_exit.xml
│ │ ├── color
│ │ ├── menu_live_text_selector.xml
│ │ └── menu_text_selector.xml
│ │ ├── drawable
│ │ ├── bg_add_player.xml
│ │ ├── bg_avatar.xml
│ │ ├── bg_btn_continue_play.xml
│ │ ├── bg_buy.xml
│ │ ├── bg_controller.xml
│ │ ├── bg_item_avatar.xml
│ │ ├── bg_item_duration.xml
│ │ ├── bg_item_follow.xml
│ │ ├── bg_item_video_player_bottom.xml
│ │ ├── bg_live_play.xml
│ │ ├── bg_main_item_buttom.xml
│ │ ├── bg_main_item_center.xml
│ │ ├── bg_main_item_dot.xml
│ │ ├── bg_main_item_full.xml
│ │ ├── bg_main_item_top.xml
│ │ ├── bg_menu_center.xml
│ │ ├── bg_menu_center2.xml
│ │ ├── bg_menu_center_live.xml
│ │ ├── bg_menu_left.xml
│ │ ├── bg_menu_left_live.xml
│ │ ├── bg_menu_right.xml
│ │ ├── bg_menu_right_live.xml
│ │ ├── bg_play.xml
│ │ ├── bg_player_bottom.xml
│ │ ├── bg_shape_draw_bottom_bg.xml
│ │ ├── bg_shape_draw_top_bg.xml
│ │ ├── bg_shiyong.xml
│ │ ├── bg_shiyong_bord.xml
│ │ ├── bg_shiyong_bord_tr.xml
│ │ ├── bg_shiyong_tr.xml
│ │ ├── fg_video_info.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── input_bg.xml
│ │ ├── input_bg2.xml
│ │ ├── item_bg_player_bottom.xml
│ │ ├── pb_bottom_progress.xml
│ │ ├── pb_video_progress.xml
│ │ ├── progressbar_drawable.xml
│ │ ├── sb_thumb.xml
│ │ ├── sb_video_progress.xml
│ │ └── tab_indicator.xml
│ │ ├── layout
│ │ ├── activity_live.xml
│ │ ├── activity_main.xml
│ │ ├── activity_pad.xml
│ │ ├── activity_pager_simple.xml
│ │ ├── activity_pip_player.xml
│ │ ├── activity_player_list.xml
│ │ ├── activity_video_assets_player.xml
│ │ ├── activity_video_cache.xml
│ │ ├── activity_video_details.xml
│ │ ├── activity_video_global_window_player.xml
│ │ ├── activity_video_perview.xml
│ │ ├── activity_video_player.xml
│ │ ├── activity_video_window_player.xml
│ │ ├── activity_videos_player.xml
│ │ ├── controller_live.xml
│ │ ├── controller_perview.xml
│ │ ├── controller_short_video.xml
│ │ ├── dialog_menu.xml
│ │ ├── dialog_project_menu.xml
│ │ ├── fragment_list_player.xml
│ │ ├── fragment_video_list.xml
│ │ ├── fragment_video_pager_player.xml
│ │ ├── item_details_header.xml
│ │ ├── item_details_video_list.xml
│ │ ├── item_main_menu.xml
│ │ ├── item_main_menu2.xml
│ │ ├── item_pager_player.xml
│ │ ├── item_unkonwn.xml
│ │ ├── item_video_list.xml
│ │ ├── item_video_list_player.xml
│ │ ├── item_video_list_title.xml
│ │ ├── video_menu_view.xml
│ │ ├── video_pager_layout.xml
│ │ ├── view_controller_danmu.xml
│ │ ├── view_danmu_paser_layout.xml
│ │ ├── view_loading_view.xml
│ │ ├── view_music_disc_layout.xml
│ │ ├── view_pager_player_controller.xml
│ │ ├── view_player_core.xml
│ │ ├── view_player_newbie.xml
│ │ ├── view_sdk_funcation.xml
│ │ └── view_title_view.xml
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_add_player.png
│ │ ├── ic_back_gray.png
│ │ ├── ic_category.png
│ │ ├── ic_default_circle.png
│ │ ├── ic_default_cover.jpg
│ │ ├── ic_dialog_bg.png
│ │ ├── ic_face.png
│ │ ├── ic_gitee.png
│ │ ├── ic_github.png
│ │ ├── ic_input.png
│ │ ├── ic_item_collection.png
│ │ ├── ic_item_comment.png
│ │ ├── ic_item_give.png
│ │ ├── ic_item_player_menu.png
│ │ ├── ic_item_share.png
│ │ ├── ic_launcher.png
│ │ ├── ic_list_empty.png
│ │ ├── ic_list_error.png
│ │ ├── ic_live_back.png
│ │ ├── ic_live_fullscreen.png
│ │ ├── ic_live_mute_false.png
│ │ ├── ic_live_mute_true.png
│ │ ├── ic_media_play.png
│ │ ├── ic_more.png
│ │ ├── ic_more_dow.png
│ │ ├── ic_music_disc.png
│ │ ├── ic_pager_comment.png
│ │ ├── ic_pager_like.png
│ │ ├── ic_pager_note.png
│ │ ├── ic_pager_play.png
│ │ ├── ic_pager_share.png
│ │ ├── ic_pegasus_progress_guide.png
│ │ ├── ic_player_cover.webp
│ │ ├── ic_player_window.webp
│ │ ├── ic_title_bg.png
│ │ ├── ic_video_eye.png
│ │ ├── ic_video_loading.png
│ │ └── ic_video_play_back.png
│ │ ├── raw
│ │ └── test.mp4
│ │ ├── values-v26
│ │ └── styles.xml
│ │ ├── values-zh-rCN
│ │ └── strings.xml
│ │ └── values
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── ids.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── android
│ └── player
│ └── ExampleUnitTest.java
├── build.gradle
├── cache
├── .gitignore
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── com
│ ├── android
│ └── iplayer
│ │ └── video
│ │ └── cache
│ │ ├── VideoCache.java
│ │ └── task
│ │ └── PreloadTask.java
│ └── danikula
│ └── videocache
│ ├── ByteArrayCache.java
│ ├── ByteArraySource.java
│ ├── Cache.java
│ ├── CacheListener.java
│ ├── CacheLog.java
│ ├── Config.java
│ ├── GetRequest.java
│ ├── HttpProxyCache.java
│ ├── HttpProxyCacheServer.java
│ ├── HttpProxyCacheServerClients.java
│ ├── HttpUrlSource.java
│ ├── IgnoreHostProxySelector.java
│ ├── InterruptedProxyCacheException.java
│ ├── Pinger.java
│ ├── Preconditions.java
│ ├── ProxyCache.java
│ ├── ProxyCacheException.java
│ ├── ProxyCacheUtils.java
│ ├── Source.java
│ ├── SourceInfo.java
│ ├── StorageUtils.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
├── config.gradle
├── doc
├── apk
│ └── iPlayer-2.1.26.apk
├── screenshot
│ ├── doc1.jpg
│ ├── doc2.jpg
│ ├── doc3.jpg
│ ├── doc4.jpg
│ ├── doc5.jpg
│ ├── doc6.jpg
│ ├── doc7.jpg
│ └── doc8.jpg
└── update
│ ├── updateLog.md
│ └── wiki.md
├── exo
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── com
│ └── android
│ └── iplayer
│ └── media
│ ├── ExoMediaSourceHelper.java
│ └── core
│ ├── ExoMediaPlayer.java
│ └── ExoPlayerFactory.java
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── ijk
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ ├── com
│ │ └── android
│ │ │ └── iplayer
│ │ │ └── media
│ │ │ ├── RawDataSourceProvider.java
│ │ │ └── core
│ │ │ ├── IJkMediaPlayer.java
│ │ │ └── IjkPlayerFactory.java
│ └── tv
│ │ └── danmaku
│ │ └── ijk
│ │ └── media
│ │ └── player
│ │ ├── AbstractMediaPlayer.java
│ │ ├── AndroidMediaPlayer.java
│ │ ├── IMediaPlayer.java
│ │ ├── ISurfaceTextureHolder.java
│ │ ├── ISurfaceTextureHost.java
│ │ ├── IjkLibLoader.java
│ │ ├── IjkMediaCodecInfo.java
│ │ ├── IjkMediaMeta.java
│ │ ├── IjkMediaPlayer.java
│ │ ├── IjkTimedText.java
│ │ ├── MediaInfo.java
│ │ ├── MediaPlayerProxy.java
│ │ ├── TextureMediaPlayer.java
│ │ ├── annotations
│ │ ├── AccessedByNative.java
│ │ └── CalledByNative.java
│ │ ├── exceptions
│ │ └── IjkMediaException.java
│ │ ├── ffmpeg
│ │ └── FFmpegApi.java
│ │ ├── misc
│ │ ├── AndroidMediaFormat.java
│ │ ├── AndroidTrackInfo.java
│ │ ├── IAndroidIO.java
│ │ ├── IMediaDataSource.java
│ │ ├── IMediaFormat.java
│ │ ├── ITrackInfo.java
│ │ ├── IjkMediaFormat.java
│ │ └── IjkTrackInfo.java
│ │ └── pragma
│ │ ├── DebugLog.java
│ │ └── Pragma.java
│ └── jniLibs
│ ├── arm64-v8a
│ ├── libijkffmpeg.so
│ ├── libijkplayer.so
│ └── libijksdl.so
│ ├── armeabi-v7a
│ ├── libijkffmpeg.so
│ ├── libijkplayer.so
│ └── libijksdl.so
│ ├── armeabi
│ ├── libijkffmpeg.so
│ ├── libijkplayer.so
│ └── libijksdl.so
│ ├── x86
│ ├── libijkffmpeg.so
│ ├── libijkplayer.so
│ └── libijksdl.so
│ └── x86_64
│ ├── libijkffmpeg.so
│ ├── libijkplayer.so
│ └── libijksdl.so
├── iplayer
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── android
│ │ └── iplayer
│ │ ├── base
│ │ ├── AbstractMediaPlayer.java
│ │ ├── BaseControlWidget.java
│ │ ├── BaseController.java
│ │ └── BasePlayer.java
│ │ ├── controller
│ │ ├── ControlWrapper.java
│ │ ├── GestureController.java
│ │ └── VideoController.java
│ │ ├── interfaces
│ │ ├── IBasePlayer.java
│ │ ├── IControllerView.java
│ │ ├── IGestureControl.java
│ │ ├── IPlayerControl.java
│ │ ├── IRenderView.java
│ │ └── IVideoController.java
│ │ ├── listener
│ │ ├── OnMediaEventListener.java
│ │ ├── OnPlayerEventListener.java
│ │ └── OnWindowActionListener.java
│ │ ├── manager
│ │ ├── IVideoManager.java
│ │ └── IWindowManager.java
│ │ ├── media
│ │ ├── IMediaPlayer.java
│ │ ├── IVideoPlayer.java
│ │ ├── MediaFactory.java
│ │ └── core
│ │ │ ├── MediaPlayer.java
│ │ │ └── MediaPlayerFactory.java
│ │ ├── model
│ │ └── PlayerState.java
│ │ ├── utils
│ │ ├── AnimationUtils.java
│ │ ├── AudioFocus.java
│ │ ├── ILogger.java
│ │ ├── PlayerUtils.java
│ │ └── ThreadPool.java
│ │ └── widget
│ │ ├── VideoPlayer.java
│ │ └── view
│ │ ├── LayoutProvider.java
│ │ ├── MediaTextureView.java
│ │ ├── ScreenOrientationRotate.java
│ │ └── WindowPlayerFloatView.java
│ └── res
│ ├── anim
│ ├── window_in.xml
│ └── window_out.xml
│ ├── drawable
│ └── player_locker_bg.xml
│ ├── layout
│ ├── player_base_video.xml
│ ├── player_video_controller.xml
│ └── player_window_float.xml
│ ├── mipmap-xxhdpi
│ ├── ic_player_locker_false.png
│ ├── ic_player_locker_true.png
│ └── ic_player_window_close.png
│ ├── values-zh-rCN
│ └── strings.xml
│ └── values
│ ├── ids.xml
│ ├── strings.xml
│ └── styles.xml
├── settings.gradle
└── widget
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
├── androidTest
└── java
│ └── com
│ └── android
│ └── iplayer
│ └── ExampleInstrumentedTest.java
├── main
├── AndroidManifest.xml
├── java
│ └── com
│ │ └── android
│ │ └── iplayer
│ │ └── widget
│ │ ├── WidgetFactory.java
│ │ ├── controls
│ │ ├── ControWindowView.java
│ │ ├── ControlCompletionView.java
│ │ ├── ControlFunctionBarView.java
│ │ ├── ControlGestureView.java
│ │ ├── ControlListView.java
│ │ ├── ControlLoadingView.java
│ │ ├── ControlStatusView.java
│ │ └── ControlToolBarView.java
│ │ └── view
│ │ └── BatteryView.java
└── res
│ ├── drawable
│ ├── player_battery_bg.xml
│ ├── player_battery_line.xml
│ ├── player_bg_bottom_controller.xml
│ ├── player_bg_bottom_list_controller.xml
│ ├── player_bg_btn_continue_play.xml
│ ├── player_bottom_progress.xml
│ ├── player_gesture_content_bg.xml
│ ├── player_gesture_content_portrait_bg.xml
│ ├── player_gesture_regulate_progress.xml
│ ├── player_progress_loading.xml
│ ├── player_seek_progress.xml
│ ├── player_seek_thumb.xml
│ └── player_surplus_time_bg.xml
│ ├── layout
│ ├── player_base_video.xml
│ ├── player_battery_view.xml
│ ├── player_control_completion.xml
│ ├── player_control_functionbar.xml
│ ├── player_control_gesture.xml
│ ├── player_control_loading.xml
│ ├── player_control_status.xml
│ ├── player_control_toolar.xml
│ ├── player_control_window.xml
│ ├── player_list_view.xml
│ ├── player_video_controller.xml
│ └── player_window_float.xml
│ ├── mipmap-xxhdpi
│ ├── ic_player_back.png
│ ├── ic_player_battery_in.png
│ ├── ic_player_brightness.png
│ ├── ic_player_full_scrrent.png
│ ├── ic_player_gesture_last.png
│ ├── ic_player_gesture_next.png
│ ├── ic_player_locker.png
│ ├── ic_player_menu.png
│ ├── ic_player_menu_dlna.png
│ ├── ic_player_menu_window.png
│ ├── ic_player_mute_false.png
│ ├── ic_player_mute_true.png
│ ├── ic_player_pause.png
│ ├── ic_player_play.png
│ ├── ic_player_replay.png
│ ├── ic_player_shadow_bottom.png
│ ├── ic_player_shadow_top.png
│ ├── ic_player_sound.png
│ ├── ic_player_sound_off.png
│ ├── ic_player_start.png
│ ├── ic_player_window_full.png
│ ├── ic_player_window_pause.png
│ ├── ic_player_window_play.png
│ └── ic_player_window_replay.png
│ ├── values-zh-rCN
│ └── strings.xml
│ └── values
│ ├── color.xml
│ ├── dimens.xml
│ └── strings.xml
└── test
└── java
└── com
└── android
└── iplayer
└── ExampleUnitTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | .idea
4 | /.idea
5 | /local.properties
6 | /.idea/caches
7 | /.idea/libraries
8 | /.idea/modules.xml
9 | /.idea/workspace.xml
10 | /.idea/navEditor.xml
11 | /.idea/assetWizardSettings.xml
12 | .DS_Store
13 | /build
14 | /captures
15 | .externalNativeBuild
16 | .cxx
17 | /assets
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /release
3 | *.keystore
4 | *.txt
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/android/player/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.android.player;
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 | assertEquals("com.android.videoplayer", appContext.getPackageName());
25 | }
26 | }
--------------------------------------------------------------------------------
/app/src/main/assets/test.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/assets/test.mp4
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/base/BaseContract.java:
--------------------------------------------------------------------------------
1 | package com.android.player.base;
2 |
3 | /**
4 | * hty_Yuye@Outlook.com
5 | * 2019/5/6
6 | * MVP Base V
7 | */
8 |
9 | public interface BaseContract {
10 | /**
11 | * presenter
12 | * @param view
13 | */
14 | interface BasePresenter{
15 | void attachView(V view);
16 | void detachView();
17 | }
18 |
19 | /**
20 | * View
21 | */
22 | interface BaseView{
23 |
24 | /**
25 | * 开始加载中
26 | */
27 | void showLoading();
28 |
29 | /**
30 | * 错误、为空回调
31 | * @param code 0:为空 -1:失败
32 | * @param errorMsg 描述信息
33 | */
34 | void showError(int code, String errorMsg);
35 | }
36 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/base/adapter/BaseMultiItemAdapter.java:
--------------------------------------------------------------------------------
1 | package com.android.player.base.adapter;
2 |
3 | import android.util.SparseIntArray;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import androidx.annotation.LayoutRes;
8 | import androidx.annotation.NonNull;
9 | import com.android.player.base.adapter.interfaces.MultiItemEntity;
10 | import com.android.player.base.adapter.widget.BaseViewHolder;
11 | import java.util.List;
12 |
13 | /**
14 | * created by hty
15 | * 2022/7/7
16 | * Desc:这是一个支持多布局类型的扩展,多条目布局类型适配器请继承此类,无比在构造方法里调用addItemType()添加你的布局类型和布局ID
17 | */
18 | public abstract class BaseMultiItemAdapter extends BaseAdapter {
19 |
20 | private SparseIntArray layouts = new SparseIntArray();//存储多条目类型和布局
21 |
22 | public BaseMultiItemAdapter(List data) {
23 | super(data);
24 | }
25 |
26 | @Override
27 | protected View getItemTypeView(@NonNull ViewGroup viewGroup, int itemType) {
28 | return LayoutInflater.from(viewGroup.getContext()).inflate(layouts.get(itemType), viewGroup, false);
29 | }
30 |
31 | @Override
32 | public int getItemViewType(int position) {
33 | if(null!=getData()&&getData().size()>position){
34 | T data = (T) getData().get(position);
35 | if(null!=data) {
36 | return data.getItemType();
37 | }
38 | }
39 | return 0;
40 | }
41 |
42 | /**
43 | * 子适配器调用此方法添加自己的不同条目View ID
44 | * @param itemType
45 | * @param layoutResId
46 | */
47 | protected void addItemType(int itemType, @LayoutRes int layoutResId){
48 | layouts.put(itemType,layoutResId);
49 | }
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/base/adapter/BaseNoimalAdapter.java:
--------------------------------------------------------------------------------
1 | package com.android.player.base.adapter;
2 |
3 | import android.view.LayoutInflater;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 | import androidx.annotation.LayoutRes;
7 | import androidx.annotation.NonNull;
8 | import com.android.player.base.adapter.widget.BaseViewHolder;
9 | import java.util.List;
10 |
11 | /**
12 | * created by hty
13 | * 2022/7/7
14 | * Desc:这是一个单条目布局类型的适配器基类,单条目布局类型适配器请继承此类
15 | */
16 | public abstract class BaseNoimalAdapter extends BaseAdapter {
17 |
18 | private int mRLayoutRes;//布局ID
19 |
20 | public BaseNoimalAdapter(@LayoutRes int resource){
21 | this(resource,null);
22 | }
23 |
24 | public BaseNoimalAdapter(List data){
25 | this(0,data);
26 | }
27 |
28 | public BaseNoimalAdapter(@LayoutRes int resource, List data){
29 | super(data);
30 | super.mData=data;
31 | this.mRLayoutRes=resource;
32 | }
33 |
34 | @Override
35 | protected View getItemTypeView(@NonNull ViewGroup viewGroup, int itemType) {
36 | return LayoutInflater.from(viewGroup.getContext()).inflate(mRLayoutRes, viewGroup, false);
37 | }
38 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/base/adapter/interfaces/MultiItemEntity.java:
--------------------------------------------------------------------------------
1 | package com.android.player.base.adapter.interfaces;
2 |
3 | /**
4 | * created by hty
5 | * 2022/7/7
6 | * Desc:多类型布局的实体类必须继承实现此接口
7 | */
8 | public interface MultiItemEntity {
9 |
10 | int getItemType();
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/base/adapter/interfaces/OnItemChildClickListener.java:
--------------------------------------------------------------------------------
1 | package com.android.player.base.adapter.interfaces;
2 |
3 | import android.view.View;
4 |
5 | /**
6 | * created by hty
7 | * 2022/7/1
8 | * Desc:
9 | */
10 | public interface OnItemChildClickListener {
11 | void onItemClick(View view, int position, long itemId);
12 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/base/adapter/interfaces/OnItemClickListener.java:
--------------------------------------------------------------------------------
1 | package com.android.player.base.adapter.interfaces;
2 |
3 | import android.view.View;
4 |
5 | /**
6 | * created by hty
7 | * 2022/7/1
8 | * Desc:
9 | */
10 | public interface OnItemClickListener {
11 | void onItemClick(View view, int position, long itemId);
12 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/base/adapter/interfaces/OnLoadMorePresenter.java:
--------------------------------------------------------------------------------
1 | package com.android.player.base.adapter.interfaces;
2 |
3 | /**
4 | * hty_Yuye@Outlook.com
5 | * 2022/7/7
6 | */
7 |
8 | public interface OnLoadMorePresenter {
9 | //加载完成
10 | void onLoadComplete();
11 | //结束,一般为空调用
12 | void onLoadEnd();
13 | //加载失败
14 | void onLoadError();
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/base/adapter/widget/BaseViewHolder.java:
--------------------------------------------------------------------------------
1 | package com.android.player.base.adapter.widget;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import androidx.annotation.NonNull;
6 | import androidx.recyclerview.widget.RecyclerView;
7 |
8 | /**
9 | * created by hty
10 | * 2022/7/1
11 | * Desc:基础的BaseViewHolder
12 | */
13 | public class BaseViewHolder extends RecyclerView.ViewHolder {
14 |
15 | public BaseViewHolder(@NonNull View itemView) {
16 | super(itemView);
17 | }
18 |
19 | public View findViewById(int id){
20 | return getView(id);
21 | }
22 |
23 | public T getView(int id) {
24 | if (null == itemView) return null;
25 | return (T) itemView.findViewById(id);
26 | }
27 |
28 | public Context getContext(){
29 | if(null!=itemView){
30 | return itemView.getContext();
31 | }
32 | return null;
33 | }
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/bean/Params.java:
--------------------------------------------------------------------------------
1 | package com.android.player.bean;
2 |
3 | /**
4 | * created by hty
5 | * 2022/7/11
6 | * Desc:这个时视频落地页接收处理悬浮窗窗口播放器时的临时中转参数
7 | */
8 | public class Params {
9 |
10 | private long id;
11 | private String listJson;
12 | private String paramsJson;
13 |
14 | public long getId() {
15 | return id;
16 | }
17 |
18 | public void setId(long id) {
19 | this.id = id;
20 | }
21 |
22 | public String getListJson() {
23 | return listJson;
24 | }
25 |
26 | public void setListJson(String listJson) {
27 | this.listJson = listJson;
28 | }
29 |
30 | public String getParamsJson() {
31 | return paramsJson;
32 | }
33 |
34 | public void setParamsJson(String paramsJson) {
35 | this.paramsJson = paramsJson;
36 | }
37 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/bean/Version.java:
--------------------------------------------------------------------------------
1 | package com.android.player.bean;
2 |
3 | /**
4 | * created by hty
5 | * 2022/8/1
6 | * Desc:预更新信息
7 | */
8 | public class Version {
9 |
10 | private String code;
11 | private String descript;
12 | private String time;
13 |
14 | public String getCode() {
15 | return code;
16 | }
17 |
18 | public void setCode(String code) {
19 | this.code = code;
20 | }
21 |
22 | public String getDescript() {
23 | return descript;
24 | }
25 |
26 | public void setDescript(String descript) {
27 | this.descript = descript;
28 | }
29 |
30 | public String getTime() {
31 | return time;
32 | }
33 |
34 | public void setTime(String time) {
35 | this.time = time;
36 | }
37 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/controller/LiveControllerControl.java:
--------------------------------------------------------------------------------
1 | package com.android.player.controller;
2 |
3 | import android.content.Context;
4 | import com.android.iplayer.base.BaseController;
5 |
6 | /**
7 | * created by hty
8 | * 2022/8/29
9 | * Desc:直播场景控制器
10 | */
11 | public class LiveControllerControl extends BaseController {
12 |
13 | public LiveControllerControl(Context context) {
14 | super(context);
15 | }
16 |
17 | @Override
18 | public int getLayoutId() {
19 | return 0;
20 | }
21 |
22 | @Override
23 | public void initViews() {
24 |
25 | }
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/net/OnDownloadListener.java:
--------------------------------------------------------------------------------
1 | package com.android.player.net;
2 |
3 | import java.io.File;
4 |
5 | /**
6 | * Created by TinyHung@outlook.com
7 | * 2019/5/15
8 | * 文件下载监听
9 | */
10 |
11 | public interface OnDownloadListener {
12 |
13 | /**
14 | * 下载百分比进度,回调在子线程
15 | * @param progress 百分比
16 | * @param totloLength 总长度
17 | * @param readLength 已下载长度
18 | */
19 | void progress(int progress, long totloLength, long readLength);
20 |
21 | /**
22 | * 下载完成
23 | * @param file 文件信息
24 | */
25 | void onSuccess(File file);
26 |
27 | /**
28 | * 下载失败
29 | * @param errorCode 错误码
30 | * @param message 描述信息
31 | */
32 | void onError(int errorCode, String message);
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/net/OnResultCallBack.java:
--------------------------------------------------------------------------------
1 | package com.android.player.net;
2 |
3 | import com.google.gson.internal.$Gson$Types;
4 | import java.lang.reflect.ParameterizedType;
5 | import java.lang.reflect.Type;
6 |
7 | /**
8 | * Created by TinyHung@outlook.com
9 | * 2019/5/8
10 | * 配合OkHttpUtils数据交互的回调抽象类,代替interface接口
11 | * @param 最终返回的实体对象数据类型,如果不指定,则返回String类型实体对象
12 | */
13 |
14 | public abstract class OnResultCallBack {
15 |
16 | //用户指定的数据类型
17 | private final Type mType;
18 |
19 | public OnResultCallBack(){
20 | mType = getClassTypeParameter(getClass());
21 | }
22 |
23 | /**
24 | * 获取当前类的多态
25 | * @param subclass class属性
26 | * @return 指定的泛型、多态
27 | */
28 | private Type getClassTypeParameter(Class> subclass) {
29 | Type superclass = subclass.getGenericSuperclass();
30 | //JVM未识别到的,泛型、多态为空
31 | if (superclass instanceof Class) {
32 | return String.class;
33 | }
34 | ParameterizedType parameterized = (ParameterizedType) superclass;
35 | return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
36 | }
37 |
38 | /**
39 | * 返回实体Type
40 | * @return 泛型对象Type
41 | */
42 | public Type getType(){
43 | return mType;
44 | }
45 |
46 | /**
47 | * 响应成功
48 | * @param data 实体对象,没有传泛型默认是String.class类型
49 | */
50 | public abstract void onResponse(T data);
51 |
52 | /**
53 | * 响应、解析失败
54 | * @param code 错误码
55 | * @param errorMsg 描述信息
56 | */
57 | public abstract void onError(int code, String errorMsg);
58 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/pager/adapter/VideoListAdapter.java:
--------------------------------------------------------------------------------
1 | package com.android.player.pager.adapter;
2 |
3 | import android.widget.FrameLayout;
4 | import android.widget.ImageView;
5 | import android.widget.TextView;
6 | import com.android.player.R;
7 | import com.android.player.base.adapter.BaseNoimalAdapter;
8 | import com.android.player.base.adapter.widget.BaseViewHolder;
9 | import com.android.player.pager.bean.VideoBean;
10 | import com.android.player.utils.GlideModel;
11 | import com.android.player.utils.ScreenUtils;
12 | import java.util.List;
13 |
14 | /**
15 | * created by hty
16 | * 2022/7/1
17 | * Desc:视频列表适配器
18 | */
19 | public class VideoListAdapter extends BaseNoimalAdapter {
20 |
21 | private final int mItemHeight;
22 |
23 | public VideoListAdapter(List data) {
24 | super(R.layout.item_video_list,data);
25 | mItemHeight = ((ScreenUtils.getInstance().getScreenWidth() - ScreenUtils.getInstance().dpToPxInt(3f)) / 2) * 16 /11;
26 | }
27 |
28 | @Override
29 | protected void initItemView(BaseViewHolder viewHolder, int position, VideoBean data) {
30 | ((TextView) viewHolder.getView(R.id.item_title)).setText(data.getFilterTitleStr());
31 | FrameLayout itemRootView = (FrameLayout) viewHolder.getView(R.id.item_root_content);
32 | itemRootView.getLayoutParams().height= mItemHeight;
33 | ImageView imageCover = (ImageView) viewHolder.getView(R.id.item_cover);
34 | GlideModel.getInstance().loadImage(imageCover,data.getCoverImgUrl());
35 | }
36 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/pager/base/BaseViewPager.java:
--------------------------------------------------------------------------------
1 | package com.android.player.pager.base;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.View;
6 | import android.widget.FrameLayout;
7 | import androidx.annotation.NonNull;
8 | import androidx.annotation.Nullable;
9 | import com.android.player.pager.interfaces.IViewPager;
10 |
11 | /**
12 | * created by hty
13 | * 2022/7/4
14 | * Desc:ViewPager 和 RecyclerView 的PagerSnapHelper通用基类
15 | */
16 | public abstract class BaseViewPager extends FrameLayout implements IViewPager {
17 |
18 | protected static final String TAG="BaseViewPager";
19 | protected int mPosition;//当前的ITEM位置
20 |
21 | public BaseViewPager(@NonNull Context context) {
22 | this(context,null);
23 | }
24 |
25 | public BaseViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
26 | this(context, attrs,0);
27 | }
28 |
29 | public BaseViewPager(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
30 | super(context, attrs, defStyleAttr);
31 | View.inflate(context,getLayoutId(),this);
32 | initViews();
33 | }
34 |
35 | /**
36 | * 返回布局文件ID
37 | * @return 布局文件ID
38 | */
39 | protected abstract int getLayoutId();
40 |
41 | /**
42 | * 初始化View
43 | */
44 | protected abstract void initViews();
45 |
46 | protected int getPosition() {
47 | return mPosition;
48 | }
49 |
50 | protected String getPositionStr(){
51 | return ",position:"+ mPosition;
52 | }
53 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/pager/interfaces/IViewPager.java:
--------------------------------------------------------------------------------
1 | package com.android.player.pager.interfaces;
2 |
3 | /**
4 | * created by hty
5 | * 2022/7/4
6 | * Desc:RecyclerView Item 或ViewPager片段扩展接口
7 | */
8 | public interface IViewPager {
9 |
10 | void prepare();//缓冲中
11 |
12 | void resume();//开始\恢复播放
13 |
14 | void pause();//暂停播放
15 |
16 | void stop();//停止播放
17 |
18 | void error();//播放失败了
19 |
20 | void onRelease();//生命周期-释放
21 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/pager/interfaces/OnViewPagerListener.java:
--------------------------------------------------------------------------------
1 | package com.android.player.pager.interfaces;
2 |
3 | import android.view.View;
4 |
5 | /**
6 | * created by hty
7 | * 2022/7/4
8 | * Desc:RecyclerView仿ViewPager的片段选择器器监听
9 | */
10 | public interface OnViewPagerListener {
11 | /**
12 | * @param view 当前正在被释放的itemView
13 | * @param isNext 是否还有下一条视频 true:有 false:没有
14 | * @param position 当前被释放的item位置
15 | */
16 | void onPageRelease(View view,boolean isNext, int position);
17 |
18 | /**
19 | * @param view 当前选中的itemView
20 | * @param position 当前选中的item位置
21 | * @param isBottom 是否滑动到底部 true:当前position已经到<=(最后一条数据-2)的位置了,在这里加载更多数据 flase:否
22 | */
23 | void onPageSelected(View view, int position, boolean isBottom);
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/pager/widget/MarqueeTextView.java:
--------------------------------------------------------------------------------
1 | package com.android.player.pager.widget;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.util.AttributeSet;
6 | import android.widget.TextView;
7 |
8 | /**
9 | * created by hty
10 | * 2022/7/5
11 | * Desc:
12 | */
13 | @SuppressLint("AppCompatCustomView")
14 | public class MarqueeTextView extends TextView {
15 |
16 | public MarqueeTextView(Context context) {
17 | super(context);
18 | }
19 |
20 | public MarqueeTextView(Context context, AttributeSet attrs) {
21 | super(context, attrs);
22 | }
23 |
24 | public boolean isFocused() {
25 | return true;
26 | }
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/ui/widget/GlideCircleTransform.java:
--------------------------------------------------------------------------------
1 | package com.android.player.ui.widget;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapShader;
5 | import android.graphics.Canvas;
6 | import android.graphics.Paint;
7 | import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
8 | import com.bumptech.glide.load.resource.bitmap.CircleCrop;
9 |
10 | /**
11 | * Created by TinyHung@outlook.com
12 | * Glide 3.x 圆形加载,实现Context构造,transform和getId。两个函数
13 | * Glide 4.x 直接继承CircleCrop,无需实现构造和任何方法
14 | */
15 | public class GlideCircleTransform extends CircleCrop {
16 |
17 | public GlideCircleTransform(){
18 |
19 | }
20 |
21 | @Override
22 | protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
23 | return circleCrop(pool, toTransform);
24 | }
25 |
26 | private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
27 | if (source == null) return null;
28 |
29 | int size = Math.min(source.getWidth(), source.getHeight());
30 | int x = (source.getWidth() - size) / 2;
31 | int y = (source.getHeight() - size) / 2;
32 | Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
33 |
34 | Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
35 | if (result == null) {
36 | result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
37 | }
38 | Canvas canvas = new Canvas(result);
39 | Paint paint = new Paint();
40 | paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
41 | paint.setAntiAlias(true);
42 | float r = size / 2f;
43 | canvas.drawCircle(r, r, r, paint);
44 | return result;
45 | }
46 |
47 | // @Override
48 | // public String getId() {
49 | //
50 | // }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/ui/widget/ListPlayerHolder.java:
--------------------------------------------------------------------------------
1 | package com.android.player.ui.widget;
2 |
3 | import android.view.View;
4 | import android.widget.FrameLayout;
5 | import androidx.annotation.NonNull;
6 | import com.android.player.R;
7 | import com.android.player.base.adapter.widget.BaseViewHolder;
8 |
9 | /**
10 | * created by hty
11 | * 2022/7/2
12 | * Desc:列表播放ViewHolder
13 | */
14 | public class ListPlayerHolder extends BaseViewHolder {
15 |
16 | private FrameLayout mPlayerContainer;
17 |
18 | public ListPlayerHolder(@NonNull View itemView) {
19 | super(itemView);
20 | if(null!=itemView&&null!=itemView.findViewById(R.id.item_player_container)){
21 | mPlayerContainer=itemView.findViewById(R.id.item_player_container);
22 | }
23 | itemView.setTag(this);
24 | }
25 |
26 | public FrameLayout getPlayerContainer() {
27 | return mPlayerContainer;
28 | }
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/utils/Logger.java:
--------------------------------------------------------------------------------
1 | package com.android.player.utils;
2 |
3 | import android.util.Log;
4 | import com.android.player.BuildConfig;
5 |
6 | /**
7 | * created by hty
8 | * 2022/7/1
9 | * Desc:
10 | */
11 | public class Logger {
12 |
13 | public static void pd(String TAG, String message){
14 | if(BuildConfig.DEBUG){
15 | Log.println(Log.DEBUG,TAG,message);
16 | }
17 | }
18 |
19 | public static void pe(String TAG, String message){
20 | if(BuildConfig.DEBUG){
21 | Log.println(Log.ERROR,TAG,message);
22 | }
23 | }
24 |
25 | public static void pw(String TAG, String message){
26 | if(BuildConfig.DEBUG){
27 | Log.println(Log.WARN,TAG,message);
28 | }
29 | }
30 |
31 | public static void pi(String TAG, String message){
32 | if(BuildConfig.DEBUG){
33 | Log.println(Log.INFO,TAG,message);
34 | }
35 | }
36 | public static void d(String TAG, String message) {
37 | if(BuildConfig.DEBUG){
38 | Log.d(TAG,message);
39 | }
40 | }
41 |
42 | public static void e(String TAG, String message) {
43 | if(BuildConfig.DEBUG){
44 | Log.e(TAG,message);
45 | }
46 | }
47 |
48 | public static void v(String TAG, String message) {
49 | if(BuildConfig.DEBUG){
50 | Log.e(TAG,message);
51 | }
52 | }
53 |
54 | public static void w(String TAG, String message) {
55 | if(BuildConfig.DEBUG){
56 | Log.w(TAG,message);
57 | }
58 | }
59 |
60 | public static void i(String TAG, String message) {
61 | if(BuildConfig.DEBUG){
62 | Log.i(TAG,message);
63 | }
64 | }
65 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/video/bean/OpenEyesAuthor.java:
--------------------------------------------------------------------------------
1 | package com.android.player.video.bean;
2 |
3 | /**
4 | * TinyHung@Outlook.com
5 | * 2019/4/8
6 | */
7 |
8 | public class OpenEyesAuthor {
9 |
10 | /**
11 | * followed : false
12 | * itemId : 2162
13 | * itemType : author
14 | */
15 | private String icon;
16 | private int id;
17 | private String name;
18 |
19 | public String getIcon() {
20 | return icon;
21 | }
22 |
23 | public void setIcon(String icon) {
24 | this.icon = icon;
25 | }
26 |
27 | public int getId() {
28 | return id;
29 | }
30 |
31 | public void setId(int id) {
32 | this.id = id;
33 | }
34 |
35 | public String getName() {
36 | return name;
37 | }
38 |
39 | public void setName(String name) {
40 | this.name = name;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/video/bean/OpenEyesContent.java:
--------------------------------------------------------------------------------
1 | package com.android.player.video.bean;
2 |
3 | /**
4 | * TinyHung@Outlook.com
5 | * 2019/4/8
6 | */
7 |
8 | public class OpenEyesContent {
9 |
10 | private long id;
11 | //squareCardCollection
12 | private String type;
13 | private OpenEyesIndexItemBean data;
14 |
15 | public long getId() {
16 | return id;
17 | }
18 |
19 | public void setId(long id) {
20 | this.id = id;
21 | }
22 |
23 | public String getType() {
24 | return type;
25 | }
26 |
27 | public void setType(String type) {
28 | this.type = type;
29 | }
30 |
31 | public OpenEyesIndexItemBean getData() {
32 | return data;
33 | }
34 |
35 | public void setData(OpenEyesIndexItemBean data) {
36 | this.data = data;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/video/bean/OpenEyesIndexInfo.java:
--------------------------------------------------------------------------------
1 | package com.android.player.video.bean;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * TinyHung@Outlook.com
7 | * 2019/4/8
8 | * 开眼视频
9 | */
10 |
11 | public class OpenEyesIndexInfo {
12 |
13 | //一维数组
14 | private List itemList;
15 |
16 | private List videoList;
17 |
18 | public List getItemList() {
19 | return itemList;
20 | }
21 |
22 | public void setItemList(List itemList) {
23 | this.itemList = itemList;
24 | }
25 |
26 | public List getVideoList() {
27 | return videoList;
28 | }
29 |
30 | public void setVideoList(List videoList) {
31 | this.videoList = videoList;
32 | }
33 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/video/contract/VideoListContract.java:
--------------------------------------------------------------------------------
1 | package com.android.player.video.contract;
2 |
3 | import com.android.player.base.BaseContract;
4 | import com.android.player.video.bean.OpenEyesIndexItemBean;
5 | import java.util.List;
6 |
7 | /**
8 | * hty_Yuye@Outlook.com
9 | * 2019/5/6
10 | * Index Video Contract
11 | */
12 |
13 | public interface VideoListContract {
14 |
15 | interface View extends BaseContract.BaseView{
16 |
17 | /**
18 | * 显示视频列表
19 | * @param data 视频列表
20 | * @param isRestart 是否从第一页开始加载的
21 | */
22 | void showVideos(List data, boolean isRestart);
23 | }
24 |
25 | interface Presenter extends BaseContract.BasePresenter{
26 |
27 | /**
28 | * 获取主页的视频列表
29 | * @param isRestart 是否重新开始?
30 | */
31 | void getIndexVideos(boolean isRestart);
32 |
33 | /**
34 | * 根据URL获取视频列表
35 | * @param url url
36 | * @param isRestart 是否从第一页开始加载的
37 | */
38 | void getVideosByUrl(String url, boolean isRestart);
39 |
40 | /**
41 | * 根据视频ID获取推荐列表
42 | * @param videoID 视频ID
43 | */
44 | void getVideosByVideo(String videoID);
45 | }
46 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/video/listener/OnMenuActionListener.java:
--------------------------------------------------------------------------------
1 | package com.android.player.video.listener;
2 |
3 | /**
4 | * created by hty
5 | * 2022/7/11
6 | * Desc:菜单功能交互监听器
7 | */
8 | public interface OnMenuActionListener {
9 | /**
10 | * @param speed 倍速 从0.5f-2.0f
11 | */
12 | void onSpeed(float speed);
13 |
14 | /**
15 | * @param zoomModel 画面缩放模式,参考IMediaPlayer定义的常量
16 | */
17 | void onZoom(int zoomModel);
18 |
19 | /**
20 | * @param scale 画面显示比例
21 | */
22 | void onScale(int scale);
23 |
24 | /**
25 | * @param mute 是否静音 true:无声 false:跟随系统音量
26 | */
27 | void onMute(boolean mute);
28 |
29 | /**
30 | * @param mirror 是否镜像翻转 true:镜像翻转 false:正常
31 | */
32 | void onMirror(boolean mirror);
33 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/android/player/video/model/IndexVideoEngin.java:
--------------------------------------------------------------------------------
1 | package com.android.player.video.model;
2 |
3 | import com.android.player.net.BaseEngin;
4 | import com.android.player.net.OnResultCallBack;
5 | import java.util.HashMap;
6 | import java.util.Map;
7 |
8 | /**
9 | * hty_Yuye@Outlook.com
10 | * 2019/5/6
11 | * Index Video Model
12 | */
13 |
14 | public class IndexVideoEngin extends BaseEngin {
15 |
16 | /**
17 | * 获取视频列为表
18 | * @param page 页眉
19 | * @param callBack 回调
20 | */
21 | public void getIndexVideos(int page, OnResultCallBack callBack){
22 | Map params=new HashMap<>();
23 | params.put("page",page+"");
24 | params.put("udid","a53873ffaa4430bbb41ea178c1187e97c4b3c4a");
25 | sendGetRequst("http://baobab.kaiyanapp.com/api/v5/index/tab/allRec",params,callBack);
26 | }
27 |
28 | /**
29 | * 根据URL获取视频列表
30 | * @param url url
31 | * @param page 页眉
32 | * @param callBack 回调
33 | */
34 | public void getVideosByUrl(String url, int page, OnResultCallBack callBack){
35 | Map params=new HashMap<>();
36 | params.put("page",page+"");
37 | params.put("udid","a53873ffaa4430bbb41ea178c1187e97c4b3c4a");
38 | sendGetRequst("http://baobab.kaiyanapp.com/api/v2/"+url,params,callBack);
39 | }
40 |
41 | /**
42 | * 根据视频ID获取视频列表
43 | * @param videoID 视频ID
44 | * @param callBack 回调
45 | */
46 | public void getVideosByVideo(String videoID, OnResultCallBack callBack){
47 | Map params=new HashMap<>();
48 | params.put("id",videoID);
49 | params.put("udid","a53873ffaa4430bbb41ea178c1187e97c4b3c4a");
50 | sendGetRequst("http://baobab.kaiyanapp.com/api/v4/video/related",params,callBack);
51 | }
52 | }
--------------------------------------------------------------------------------
/app/src/main/res/anim/bottom_menu_enter.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/bottom_menu_exit.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/color/menu_live_text_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/color/menu_text_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_add_player.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_avatar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_btn_continue_play.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_buy.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_controller.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_item_avatar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_item_duration.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_item_follow.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_item_video_player_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_live_play.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_main_item_buttom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_main_item_center.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_main_item_dot.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_main_item_full.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_main_item_top.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_menu_center.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_menu_center2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_menu_center_live.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 | -
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_menu_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 | -
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_menu_left_live.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_menu_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 | -
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_menu_right_live.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_play.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_player_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_shape_draw_bottom_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_shape_draw_top_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_shiyong.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_shiyong_bord.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_shiyong_bord_tr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_shiyong_tr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/fg_video_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/input_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/input_bg2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/item_bg_player_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/pb_bottom_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 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/pb_video_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 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/progressbar_drawable.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/sb_thumb.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
15 | -
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/sb_video_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 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/tab_indicator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
12 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_pad.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
12 |
13 |
17 |
23 |
28 |
29 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_pip_player.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
12 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_player_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
11 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_video_assets_player.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
11 |
12 |
16 |
22 |
26 |
27 |
32 |
37 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_video_global_window_player.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
11 |
12 |
16 |
22 |
26 |
27 |
34 |
42 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_video_perview.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
11 |
12 |
16 |
22 |
27 |
28 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_video_window_player.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
11 |
12 |
17 |
21 |
22 |
25 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/controller_live.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
13 |
22 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/controller_short_video.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
13 |
17 |
22 |
27 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_list_player.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
15 |
19 |
23 |
27 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_video_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
13 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_pager_player.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_unkonwn.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_video_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
13 |
18 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_video_list_title.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/video_pager_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
11 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_controller_danmu.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
11 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_danmu_paser_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_loading_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
13 |
16 |
21 |
28 |
29 |
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_music_disc_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_player_newbie.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
14 |
19 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_title_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
13 |
18 |
22 |
25 |
35 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_add_player.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_add_player.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_back_gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_back_gray.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_category.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_category.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_default_circle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_default_circle.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_default_cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_default_cover.jpg
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_dialog_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_dialog_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_face.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_face.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_gitee.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_gitee.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_github.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_input.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_input.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_item_collection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_item_collection.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_item_comment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_item_comment.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_item_give.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_item_give.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_item_player_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_item_player_menu.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_item_share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_item_share.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_list_empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_list_empty.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_list_error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_list_error.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_live_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_live_back.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_live_fullscreen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_live_fullscreen.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_live_mute_false.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_live_mute_false.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_live_mute_true.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_live_mute_true.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_media_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_media_play.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_more.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_more.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_more_dow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_more_dow.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_music_disc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_music_disc.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_pager_comment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_pager_comment.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_pager_like.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_pager_like.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_pager_note.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_pager_note.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_pager_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_pager_play.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_pager_share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_pager_share.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_pegasus_progress_guide.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_pegasus_progress_guide.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_player_cover.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_player_cover.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_player_window.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_player_window.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_title_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_title_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_video_eye.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_video_eye.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_video_loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_video_loading.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_video_play_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/mipmap-xxhdpi/ic_video_play_back.png
--------------------------------------------------------------------------------
/app/src/main/res/raw/test.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/app/src/main/res/raw/test.mp4
--------------------------------------------------------------------------------
/app/src/main/res/values-v26/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
13 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #000000
4 | #000000
5 | #1DBA5B
6 | #00000000
7 | #FFFFFF
8 | #333333
9 | #72747B
10 | #666666
11 | #888888
12 | #4DFFFFFF
13 | #33E5E5E5
14 | #FFFFFF
15 | #F2F6FA
16 |
--------------------------------------------------------------------------------
/app/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/test/java/com/android/player/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.android.player;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | apply from: "config.gradle"
3 |
4 | buildscript {
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath "com.android.tools.build:gradle:4.0.1"
11 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | google()
18 | jcenter()
19 | //本地Maven仓库地址,取决于你的磁盘目录
20 | // maven { url 'file://D://AndroidStudioProjects//iPlayer//maven' }
21 | maven { url 'https://jitpack.io' }
22 | }
23 | //编译时报注释GBK编码错误解决
24 | tasks.withType(Javadoc) {
25 | //方法上忽略@return和@param注解未添加说明注释
26 | options.addStringOption('Xdoclint:none', '-quiet')
27 | //解决GBK编码错误提示
28 | options.addStringOption('encoding', 'UTF-8')
29 | options.addStringOption('charSet', 'UTF-8')
30 | }
31 | //跳过构建时link检查
32 | tasks.whenTaskAdded { task ->
33 | if (task.name.equals("lint")) {
34 | task.enabled = false
35 | }
36 | }
37 | }
38 | //当androidx.core 版本冲突时,强制gradle使用指定版本
39 | subprojects {
40 | project.configurations.all {
41 | resolutionStrategy.eachDependency {
42 | details -> if (details.requested.group == 'androidx.core' && !details.requested.name.contains('androidx'))
43 | { details.useVersion "1.6.0" }
44 | }
45 | }
46 | }
47 |
48 | task clean(type: Delete) {
49 | delete rootProject.buildDir
50 | }
--------------------------------------------------------------------------------
/cache/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/cache/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | //发布到jitpack应用配置
3 | apply plugin: 'com.github.dcendents.android-maven'
4 | group='com.github.hty527'//xxx:代表你的github用户名
5 |
6 | android {
7 | compileSdkVersion 30
8 | buildToolsVersion "30.0.2"
9 |
10 | defaultConfig {
11 | minSdkVersion 16
12 | targetSdkVersion 30
13 | versionCode rootProject.ext.sdk.versionCode
14 | versionName rootProject.ext.sdk.versionName
15 | }
16 | lintOptions {
17 | abortOnError false
18 | }
19 | }
20 |
21 | // 打包源码jar
22 | task sourcesJar(type: Jar) {
23 | from android.sourceSets.main.java.srcDirs
24 | archiveClassifier = 'sources'
25 | }
26 | dependencies {
27 | implementation fileTree(dir: "libs", include: ["*.jar"])
28 | }
--------------------------------------------------------------------------------
/cache/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/ByteArrayCache.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache;
2 |
3 | import java.io.ByteArrayInputStream;
4 | import java.util.Arrays;
5 |
6 | /**
7 | * Simple memory based {@link Cache} implementation.
8 | *
9 | * @author Alexey Danilov (danikula@gmail.com).
10 | */
11 | public class ByteArrayCache implements Cache {
12 |
13 | private volatile byte[] data;
14 | private volatile boolean completed;
15 |
16 | public ByteArrayCache() {
17 | this(new byte[0]);
18 | }
19 |
20 | public ByteArrayCache(byte[] data) {
21 | this.data = Preconditions.checkNotNull(data);
22 | }
23 |
24 | @Override
25 | public int read(byte[] buffer, long offset, int length) throws ProxyCacheException {
26 | if (offset >= data.length) {
27 | return -1;
28 | }
29 | if (offset > Integer.MAX_VALUE) {
30 | throw new IllegalArgumentException("Too long offset for memory cache " + offset);
31 | }
32 | return new ByteArrayInputStream(data).read(buffer, (int) offset, length);
33 | }
34 |
35 | @Override
36 | public long available() throws ProxyCacheException {
37 | return data.length;
38 | }
39 |
40 | @Override
41 | public void append(byte[] newData, int length) throws ProxyCacheException {
42 | Preconditions.checkNotNull(data);
43 | Preconditions.checkArgument(length >= 0 && length <= newData.length);
44 |
45 | byte[] appendedData = Arrays.copyOf(data, data.length + length);
46 | System.arraycopy(newData, 0, appendedData, data.length, length);
47 | data = appendedData;
48 | }
49 |
50 | @Override
51 | public void close() throws ProxyCacheException {
52 | }
53 |
54 | @Override
55 | public void complete() {
56 | completed = true;
57 | }
58 |
59 | @Override
60 | public boolean isCompleted() {
61 | return completed;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/ByteArraySource.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache;
2 |
3 | import java.io.ByteArrayInputStream;
4 |
5 | /**
6 | * Simple memory based {@link Source} implementation.
7 | *
8 | * @author Alexey Danilov (danikula@gmail.com).
9 | */
10 | public class ByteArraySource implements Source {
11 |
12 | private final byte[] data;
13 | private ByteArrayInputStream arrayInputStream;
14 |
15 | public ByteArraySource(byte[] data) {
16 | this.data = data;
17 | }
18 |
19 | @Override
20 | public int read(byte[] buffer) throws ProxyCacheException {
21 | return arrayInputStream.read(buffer, 0, buffer.length);
22 | }
23 |
24 | @Override
25 | public long length() throws ProxyCacheException {
26 | return data.length;
27 | }
28 |
29 | @Override
30 | public void open(long offset) throws ProxyCacheException {
31 | arrayInputStream = new ByteArrayInputStream(data);
32 | arrayInputStream.skip(offset);
33 | }
34 |
35 | @Override
36 | public void close() throws ProxyCacheException {
37 | }
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/Cache.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache;
2 |
3 | /**
4 | * Cache for proxy.
5 | *
6 | * @author Alexey Danilov (danikula@gmail.com).
7 | */
8 | public interface Cache {
9 |
10 | long available() throws ProxyCacheException;
11 |
12 | int read(byte[] buffer, long offset, int length) throws ProxyCacheException;
13 |
14 | void append(byte[] data, int length) throws ProxyCacheException;
15 |
16 | void close() throws ProxyCacheException;
17 |
18 | void complete() throws ProxyCacheException;
19 |
20 | boolean isCompleted();
21 | }
22 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/CacheListener.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache;
2 |
3 | import java.io.File;
4 |
5 | /**
6 | * Listener for cache availability.
7 | *
8 | * @author Egor Makovsky (yahor.makouski@gmail.com)
9 | * @author Alexey Danilov (danikula@gmail.com).
10 | */
11 | public interface CacheListener {
12 |
13 | void onCacheAvailable(File cacheFile, String url, int percentsAvailable);
14 | }
15 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/CacheLog.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache;
2 |
3 | import android.util.Log;
4 |
5 | /**
6 | * created by hty
7 | * 2022/12/28
8 | * Desc:
9 | */
10 | public class CacheLog {
11 |
12 | private static final String TAG = "CacheLog";
13 |
14 | public static void log(String content){
15 | Log.d(TAG,content);
16 | }
17 |
18 |
19 | public static void warn(String content) {
20 | warn(content,null);
21 | }
22 |
23 | public static void warn(String content, Exception e) {
24 | try {
25 | Log.w(TAG,content+(null!=e?e.getMessage():""));
26 | }catch (Throwable e1){}
27 | }
28 |
29 | public static void debug(String content) {
30 | Log.d(TAG,content);
31 | }
32 |
33 | public static void error(String error) {
34 | error(error,null);
35 | }
36 |
37 | public static void error(String error, Throwable e) {
38 | try {
39 | Log.e(TAG,error+(null!=e?e.getMessage():""));
40 | }catch (Throwable e1){}
41 | }
42 |
43 | public static void info(String content) {
44 | Log.i(TAG,content);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/Config.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache;
2 |
3 | import com.danikula.videocache.file.DiskUsage;
4 | import com.danikula.videocache.file.FileNameGenerator;
5 | import com.danikula.videocache.headers.HeaderInjector;
6 | import com.danikula.videocache.sourcestorage.SourceInfoStorage;
7 |
8 | import java.io.File;
9 |
10 | /**
11 | * Configuration for proxy cache.
12 | *
13 | * @author Alexey Danilov (danikula@gmail.com).
14 | */
15 | class Config {
16 |
17 | public final File cacheRoot;
18 | public final FileNameGenerator fileNameGenerator;
19 | public final DiskUsage diskUsage;
20 | public final SourceInfoStorage sourceInfoStorage;
21 | public final HeaderInjector headerInjector;
22 |
23 | Config(File cacheRoot, FileNameGenerator fileNameGenerator, DiskUsage diskUsage, SourceInfoStorage sourceInfoStorage, HeaderInjector headerInjector) {
24 | this.cacheRoot = cacheRoot;
25 | this.fileNameGenerator = fileNameGenerator;
26 | this.diskUsage = diskUsage;
27 | this.sourceInfoStorage = sourceInfoStorage;
28 | this.headerInjector = headerInjector;
29 | }
30 |
31 | File generateCacheFile(String url) {
32 | String name = fileNameGenerator.generate(url);
33 | return new File(cacheRoot, name);
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/InterruptedProxyCacheException.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache;
2 |
3 | /**
4 | * Indicates interruption error in work of {@link ProxyCache} fired by user.
5 | *
6 | * @author Alexey Danilov
7 | */
8 | public class InterruptedProxyCacheException extends ProxyCacheException {
9 |
10 | public InterruptedProxyCacheException(String message) {
11 | super(message);
12 | }
13 |
14 | public InterruptedProxyCacheException(String message, Throwable cause) {
15 | super(message, cause);
16 | }
17 |
18 | public InterruptedProxyCacheException(Throwable cause) {
19 | super(cause);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/Preconditions.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache;
2 |
3 | public final class Preconditions {
4 |
5 | public static T checkNotNull(T reference) {
6 | if (reference == null) {
7 | throw new NullPointerException();
8 | }
9 | return reference;
10 | }
11 |
12 | public static void checkAllNotNull(Object... references) {
13 | for (Object reference : references) {
14 | if (reference == null) {
15 | throw new NullPointerException();
16 | }
17 | }
18 | }
19 |
20 | public static T checkNotNull(T reference, String errorMessage) {
21 | if (reference == null) {
22 | throw new NullPointerException(errorMessage);
23 | }
24 | return reference;
25 | }
26 |
27 | static void checkArgument(boolean expression) {
28 | if (!expression) {
29 | throw new IllegalArgumentException();
30 | }
31 | }
32 |
33 | static void checkArgument(boolean expression, String errorMessage) {
34 | if (!expression) {
35 | throw new IllegalArgumentException(errorMessage);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/ProxyCacheException.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache;
2 |
3 | /**
4 | * Indicates any error in work of {@link ProxyCache}.
5 | *
6 | * @author Alexey Danilov
7 | */
8 | public class ProxyCacheException extends Exception {
9 |
10 | private static final String LIBRARY_VERSION = "";
11 |
12 | public ProxyCacheException(String message) {
13 | super(message + LIBRARY_VERSION);
14 | }
15 |
16 | public ProxyCacheException(String message, Throwable cause) {
17 | super(message + LIBRARY_VERSION, cause);
18 | }
19 |
20 | public ProxyCacheException(Throwable cause) {
21 | super("No explanation error" + LIBRARY_VERSION, cause);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/Source.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache;
2 |
3 | /**
4 | * Source for proxy.
5 | *
6 | * @author Alexey Danilov (danikula@gmail.com).
7 | */
8 | public interface Source {
9 |
10 | /**
11 | * Opens source. Source should be open before using {@link #read(byte[])}
12 | *
13 | * @param offset offset in bytes for source.
14 | * @throws ProxyCacheException if error occur while opening source.
15 | */
16 | void open(long offset) throws ProxyCacheException;
17 |
18 | /**
19 | * Returns length bytes or negative value if length is unknown.
20 | *
21 | * @return bytes length
22 | * @throws ProxyCacheException if error occur while fetching source data.
23 | */
24 | long length() throws ProxyCacheException;
25 |
26 | /**
27 | * Read data to byte buffer from source with current offset.
28 | *
29 | * @param buffer a buffer to be used for reading data.
30 | * @return a count of read bytes
31 | * @throws ProxyCacheException if error occur while reading source.
32 | */
33 | int read(byte[] buffer) throws ProxyCacheException;
34 |
35 | /**
36 | * Closes source and release resources. Every opened source should be closed.
37 | *
38 | * @throws ProxyCacheException if error occur while closing source.
39 | */
40 | void close() throws ProxyCacheException;
41 | }
42 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/SourceInfo.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache;
2 |
3 | /**
4 | * Stores source's info.
5 | *
6 | * @author Alexey Danilov (danikula@gmail.com).
7 | */
8 | public class SourceInfo {
9 |
10 | public final String url;
11 | public final long length;
12 | public final String mime;
13 |
14 | public SourceInfo(String url, long length, String mime) {
15 | this.url = url;
16 | this.length = length;
17 | this.mime = mime;
18 | }
19 |
20 | @Override
21 | public String toString() {
22 | return "SourceInfo{" +
23 | "url='" + url + '\'' +
24 | ", length=" + length +
25 | ", mime='" + mime + '\'' +
26 | '}';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/file/DiskUsage.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache.file;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 |
6 | /**
7 | * Declares how {@link FileCache} will use disc space.
8 | *
9 | * @author Alexey Danilov (danikula@gmail.com).
10 | */
11 | public interface DiskUsage {
12 |
13 | void touch(File file) throws IOException;
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/file/FileNameGenerator.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache.file;
2 |
3 | /**
4 | * Generator for files to be used for caching.
5 | *
6 | * @author Alexey Danilov (danikula@gmail.com).
7 | */
8 | public interface FileNameGenerator {
9 |
10 | String generate(String url);
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/file/Md5FileNameGenerator.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache.file;
2 |
3 | import android.text.TextUtils;
4 |
5 | import com.danikula.videocache.ProxyCacheUtils;
6 |
7 | /**
8 | * Implementation of {@link FileNameGenerator} that uses MD5 of url as file name
9 | *
10 | * @author Alexey Danilov (danikula@gmail.com).
11 | */
12 | public class Md5FileNameGenerator implements FileNameGenerator {
13 |
14 | private static final int MAX_EXTENSION_LENGTH = 4;
15 |
16 | @Override
17 | public String generate(String url) {
18 | String extension = getExtension(url);
19 | String name = ProxyCacheUtils.computeMD5(url);
20 | return TextUtils.isEmpty(extension) ? name : name + "." + extension;
21 | }
22 |
23 | private String getExtension(String url) {
24 | int dotIndex = url.lastIndexOf('.');
25 | int slashIndex = url.lastIndexOf('/');
26 | return dotIndex != -1 && dotIndex > slashIndex && dotIndex + 2 + MAX_EXTENSION_LENGTH > url.length() ?
27 | url.substring(dotIndex + 1, url.length()) : "";
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/file/TotalCountLruDiskUsage.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache.file;
2 |
3 | import java.io.File;
4 |
5 | /**
6 | * {@link DiskUsage} that uses LRU (Least Recently Used) strategy and trims cache size to max files count if needed.
7 | *
8 | * @author Alexey Danilov (danikula@gmail.com).
9 | */
10 | public class TotalCountLruDiskUsage extends LruDiskUsage {
11 |
12 | private final int maxCount;
13 |
14 | public TotalCountLruDiskUsage(int maxCount) {
15 | if (maxCount <= 0) {
16 | throw new IllegalArgumentException("Max count must be positive number!");
17 | }
18 | this.maxCount = maxCount;
19 | }
20 |
21 | @Override
22 | protected boolean accept(File file, long totalSize, int totalCount) {
23 | return totalCount <= maxCount;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/file/TotalSizeLruDiskUsage.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache.file;
2 |
3 | import java.io.File;
4 |
5 | /**
6 | * {@link DiskUsage} that uses LRU (Least Recently Used) strategy and trims cache size to max size if needed.
7 | *
8 | * @author Alexey Danilov (danikula@gmail.com).
9 | */
10 | public class TotalSizeLruDiskUsage extends LruDiskUsage {
11 |
12 | private final long maxSize;
13 |
14 | public TotalSizeLruDiskUsage(long maxSize) {
15 | if (maxSize <= 0) {
16 | throw new IllegalArgumentException("Max size must be positive number!");
17 | }
18 | this.maxSize = maxSize;
19 | }
20 |
21 | @Override
22 | protected boolean accept(File file, long totalSize, int totalCount) {
23 | return totalSize <= maxSize;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/file/UnlimitedDiskUsage.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache.file;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 |
6 | /**
7 | * Unlimited version of {@link DiskUsage}.
8 | *
9 | * @author Alexey Danilov (danikula@gmail.com).
10 | */
11 | public class UnlimitedDiskUsage implements DiskUsage {
12 |
13 | @Override
14 | public void touch(File file) throws IOException {
15 | // do nothing
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/headers/EmptyHeadersInjector.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache.headers;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * Empty {@link HeaderInjector} implementation.
8 | *
9 | * @author Lucas Nelaupe (https://github.com/lucas34).
10 | */
11 | public class EmptyHeadersInjector implements HeaderInjector {
12 |
13 | @Override
14 | public Map addHeaders(String url) {
15 | return new HashMap<>();
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/headers/HeaderInjector.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache.headers;
2 |
3 | import java.util.Map;
4 |
5 | /**
6 | * Allows to add custom headers to server's requests.
7 | *
8 | * @author Lucas Nelaupe (https://github.com/lucas34).
9 | */
10 | public interface HeaderInjector {
11 |
12 | /**
13 | * Adds headers to server's requests for corresponding url.
14 | *
15 | * @param url an url headers will be added for
16 | * @return a map with headers, where keys are header's names, and values are header's values. {@code null} is not acceptable!
17 | */
18 | Map addHeaders(String url);
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/sourcestorage/NoSourceInfoStorage.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache.sourcestorage;
2 |
3 | import com.danikula.videocache.SourceInfo;
4 |
5 | /**
6 | * {@link SourceInfoStorage} that does nothing.
7 | *
8 | * @author Alexey Danilov (danikula@gmail.com).
9 | */
10 | public class NoSourceInfoStorage implements SourceInfoStorage {
11 |
12 | @Override
13 | public SourceInfo get(String url) {
14 | return null;
15 | }
16 |
17 | @Override
18 | public void put(String url, SourceInfo sourceInfo) {
19 | }
20 |
21 | @Override
22 | public void release() {
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/sourcestorage/SourceInfoStorage.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache.sourcestorage;
2 |
3 | import com.danikula.videocache.SourceInfo;
4 |
5 | /**
6 | * Storage for {@link SourceInfo}.
7 | *
8 | * @author Alexey Danilov (danikula@gmail.com).
9 | */
10 | public interface SourceInfoStorage {
11 |
12 | SourceInfo get(String url);
13 |
14 | void put(String url, SourceInfo sourceInfo);
15 |
16 | void release();
17 | }
18 |
--------------------------------------------------------------------------------
/cache/src/main/java/com/danikula/videocache/sourcestorage/SourceInfoStorageFactory.java:
--------------------------------------------------------------------------------
1 | package com.danikula.videocache.sourcestorage;
2 |
3 | import android.content.Context;
4 |
5 | /**
6 | * Simple factory for {@link SourceInfoStorage}.
7 | *
8 | * @author Alexey Danilov (danikula@gmail.com).
9 | */
10 | public class SourceInfoStorageFactory {
11 |
12 | public static SourceInfoStorage newSourceInfoStorage(Context context) {
13 | return new DatabaseSourceInfoStorage(context);
14 | }
15 |
16 | public static SourceInfoStorage newEmptySourceInfoStorage() {
17 | return new NoSourceInfoStorage();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/config.gradle:
--------------------------------------------------------------------------------
1 | ext {
2 | sdk=[
3 | versionCode : 20126,
4 | versionName : "2.1.26.1"//SDK版本号
5 | ]
6 | }
--------------------------------------------------------------------------------
/doc/apk/iPlayer-2.1.26.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/doc/apk/iPlayer-2.1.26.apk
--------------------------------------------------------------------------------
/doc/screenshot/doc1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/doc/screenshot/doc1.jpg
--------------------------------------------------------------------------------
/doc/screenshot/doc2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/doc/screenshot/doc2.jpg
--------------------------------------------------------------------------------
/doc/screenshot/doc3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/doc/screenshot/doc3.jpg
--------------------------------------------------------------------------------
/doc/screenshot/doc4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/doc/screenshot/doc4.jpg
--------------------------------------------------------------------------------
/doc/screenshot/doc5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/doc/screenshot/doc5.jpg
--------------------------------------------------------------------------------
/doc/screenshot/doc6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/doc/screenshot/doc6.jpg
--------------------------------------------------------------------------------
/doc/screenshot/doc7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/doc/screenshot/doc7.jpg
--------------------------------------------------------------------------------
/doc/screenshot/doc8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/doc/screenshot/doc8.jpg
--------------------------------------------------------------------------------
/exo/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/exo/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | //发布到jitpack应用配置
3 | apply plugin: 'com.github.dcendents.android-maven'
4 | group='com.github.hty527'//xxx:代表你的github用户名
5 |
6 | android {
7 | compileSdkVersion 30
8 | buildToolsVersion "30.0.2"
9 |
10 | defaultConfig {
11 | minSdkVersion 16
12 | targetSdkVersion 30
13 | versionCode rootProject.ext.sdk.versionCode
14 | versionName rootProject.ext.sdk.versionName
15 | }
16 | lintOptions {
17 | abortOnError false
18 | }
19 | }
20 |
21 | // 打包源码jar
22 | task sourcesJar(type: Jar) {
23 | from android.sourceSets.main.java.srcDirs
24 | archiveClassifier = 'sources'
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: "libs", include: ["*.jar"])
29 | //播放器
30 | implementation project(':iplayer')
31 | //SDK内部实现EXO解码器逻辑,必须依赖
32 | api 'com.google.android.exoplayer:exoplayer:2.18.1'
33 | api 'com.google.android.exoplayer:exoplayer-core:2.18.1'//核心功能(必需)
34 | api "com.google.android.exoplayer:extension-rtmp:2.18.1"//rtmp直播流解码协议
35 | //以下为可选依赖,请根据需要实现
36 | //api 'com.google.android.exoplayer:exoplayer-dash:2.18.1'//支持DASH内容
37 | //api "com.google.android.exoplayer:exoplayer-hls:2.18.1"//支持HLS内容
38 | //api "com.google.android.exoplayer:exoplayer-smoothstreaming:2.18.1"//支持SmoothStreaming内容
39 | //api "com.google.android.exoplayer:exoplayer-transformer:2.18.1"//媒体转换功能,需要minSdkVersion>=21
40 | //api "com.google.android.exoplayer:exoplayer-rtsp:2.18.1"//rtsp直播流解码协议
41 | //api 'com.google.android.exoplayer:exoplayer-ui:2.18.1'//用于ExoPlayer的UI组件和资源
42 | }
--------------------------------------------------------------------------------
/exo/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 | # ExoPlayer
23 | -keep class com.google.android.exoplayer2.** { *; }
24 | -dontwarn com.google.android.exoplayer2.**
--------------------------------------------------------------------------------
/exo/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/exo/src/main/java/com/android/iplayer/media/core/ExoPlayerFactory.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.media.core;
2 |
3 | import android.content.Context;
4 | import com.android.iplayer.media.MediaFactory;
5 |
6 | /**
7 | * created by hty
8 | * 2022/9/15
9 | * Desc:ExoPlayer播放解码器的工厂类,{@link ExoMediaPlayer}
10 | */
11 | public class ExoPlayerFactory extends MediaFactory {
12 |
13 | public static ExoPlayerFactory create() {
14 | return new ExoPlayerFactory();
15 | }
16 |
17 | @Override
18 | public ExoMediaPlayer createPlayer(Context context) {
19 | return new ExoMediaPlayer(context);
20 | }
21 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | android.enableJetifier=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Jun 28 16:26:02 CST 2022
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-6.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/ijk/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/ijk/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | //发布到jitpack应用配置
3 | apply plugin: 'com.github.dcendents.android-maven'
4 | group='com.github.hty527'//xxx:代表你的github用户名
5 |
6 | android {
7 | compileSdkVersion 30
8 | buildToolsVersion "30.0.2"
9 |
10 | defaultConfig {
11 | minSdkVersion 16
12 | targetSdkVersion 30
13 | versionCode rootProject.ext.sdk.versionCode
14 | versionName rootProject.ext.sdk.versionName
15 | }
16 | lintOptions {
17 | abortOnError false
18 | }
19 | }
20 |
21 | // 打包源码jar
22 | task sourcesJar(type: Jar) {
23 | from android.sourceSets.main.java.srcDirs
24 | archiveClassifier = 'sources'
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: "libs", include: ["*.jar"])
29 | //播放器
30 | implementation project(':iplayer')
31 | }
--------------------------------------------------------------------------------
/ijk/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 | # IjkPlayer
24 | -keep class tv.danmaku.ijk.** { *; }
25 | -dontwarn tv.danmaku.ijk.**
--------------------------------------------------------------------------------
/ijk/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/ijk/src/main/java/com/android/iplayer/media/core/IjkPlayerFactory.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.media.core;
2 |
3 | import android.content.Context;
4 | import com.android.iplayer.media.MediaFactory;
5 |
6 | /**
7 | * created by hty
8 | * 2022/9/15
9 | * Desc:IjkPlayer播放解码器的工厂类,{@link IJkMediaPlayer}
10 | */
11 | public class IjkPlayerFactory extends MediaFactory {
12 |
13 | private static boolean isLive=false;
14 |
15 | public static IjkPlayerFactory create() {
16 | return create(false);
17 | }
18 |
19 | /**
20 | * 直播模式下{@link IJkMediaPlayer}内部会针对直播拉流做一些基础设置,当然也可以你自己获取到player来自定义设置
21 | * @param isLive true:直播模式 false:非直播模式
22 | * @return
23 | */
24 | public static IjkPlayerFactory create(boolean isLive) {
25 | IjkPlayerFactory.isLive=isLive;
26 | return new IjkPlayerFactory();
27 | }
28 |
29 | @Override
30 | public IJkMediaPlayer createPlayer(Context context) {
31 | return new IJkMediaPlayer(context,isLive);
32 | }
33 | }
--------------------------------------------------------------------------------
/ijk/src/main/java/tv/danmaku/ijk/media/player/ISurfaceTextureHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Bilibili
3 | * Copyright (C) 2015 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player;
19 |
20 | import android.graphics.SurfaceTexture;
21 |
22 | public interface ISurfaceTextureHolder {
23 | void setSurfaceTexture(SurfaceTexture surfaceTexture);
24 |
25 | SurfaceTexture getSurfaceTexture();
26 |
27 | void setSurfaceTextureHost(ISurfaceTextureHost surfaceTextureHost);
28 | }
29 |
--------------------------------------------------------------------------------
/ijk/src/main/java/tv/danmaku/ijk/media/player/ISurfaceTextureHost.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Bilibili
3 | * Copyright (C) 2015 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player;
19 |
20 | import android.graphics.SurfaceTexture;
21 |
22 | public interface ISurfaceTextureHost {
23 | void releaseSurfaceTexture(SurfaceTexture surfaceTexture);
24 | }
25 |
--------------------------------------------------------------------------------
/ijk/src/main/java/tv/danmaku/ijk/media/player/IjkLibLoader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013-2014 Bilibili
3 | * Copyright (C) 2013-2014 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player;
19 |
20 | public interface IjkLibLoader {
21 | void loadLibrary(String libName) throws UnsatisfiedLinkError,
22 | SecurityException;
23 | }
24 |
--------------------------------------------------------------------------------
/ijk/src/main/java/tv/danmaku/ijk/media/player/IjkTimedText.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Zheng Yuan
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 tv.danmaku.ijk.media.player;
18 |
19 | import android.graphics.Rect;
20 | import java.lang.String;
21 |
22 | public final class IjkTimedText {
23 |
24 | private Rect mTextBounds = null;
25 | private String mTextChars = null;
26 |
27 | public IjkTimedText(Rect bounds, String text) {
28 | mTextBounds = bounds;
29 | mTextChars = text;
30 | }
31 |
32 | public Rect getBounds() {
33 | return mTextBounds;
34 | }
35 |
36 | public String getText() {
37 | return mTextChars;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/ijk/src/main/java/tv/danmaku/ijk/media/player/MediaInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013-2014 Bilibili
3 | * Copyright (C) 2013-2014 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player;
19 |
20 | public class MediaInfo {
21 | public String mMediaPlayerName;
22 |
23 | public String mVideoDecoder;
24 | public String mVideoDecoderImpl;
25 |
26 | public String mAudioDecoder;
27 | public String mAudioDecoderImpl;
28 |
29 | public IjkMediaMeta mMeta;
30 | }
31 |
--------------------------------------------------------------------------------
/ijk/src/main/java/tv/danmaku/ijk/media/player/annotations/AccessedByNative.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013-2014 Bilibili
3 | * Copyright (C) 2013-2014 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.annotations;
19 |
20 | import java.lang.annotation.ElementType;
21 | import java.lang.annotation.Retention;
22 | import java.lang.annotation.RetentionPolicy;
23 | import java.lang.annotation.Target;
24 |
25 | /**
26 | * is used by the JNI generator to create the necessary JNI
27 | * bindings and expose this method to native code.
28 | */
29 | @Target(ElementType.FIELD)
30 | @Retention(RetentionPolicy.CLASS)
31 | public @interface AccessedByNative {
32 | }
--------------------------------------------------------------------------------
/ijk/src/main/java/tv/danmaku/ijk/media/player/annotations/CalledByNative.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013-2014 Bilibili
3 | * Copyright (C) 2013-2014 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.annotations;
19 |
20 | import java.lang.annotation.ElementType;
21 | import java.lang.annotation.Retention;
22 | import java.lang.annotation.RetentionPolicy;
23 | import java.lang.annotation.Target;
24 |
25 | /**
26 | * is used by the JNI generator to create the necessary JNI
27 | * bindings and expose this method to native code.
28 | */
29 | @Target(ElementType.METHOD)
30 | @Retention(RetentionPolicy.CLASS)
31 | public @interface CalledByNative {
32 | /*
33 | * If present, tells which inner class the method belongs to.
34 | */
35 | String value() default "";
36 | }
--------------------------------------------------------------------------------
/ijk/src/main/java/tv/danmaku/ijk/media/player/exceptions/IjkMediaException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013-2014 Bilibili
3 | * Copyright (C) 2013-2014 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.exceptions;
19 |
20 | public class IjkMediaException extends Exception {
21 | private static final long serialVersionUID = 7234796519009099506L;
22 | }
23 |
--------------------------------------------------------------------------------
/ijk/src/main/java/tv/danmaku/ijk/media/player/ffmpeg/FFmpegApi.java:
--------------------------------------------------------------------------------
1 | package tv.danmaku.ijk.media.player.ffmpeg;
2 |
3 | public class FFmpegApi {
4 | public static native String av_base64_encode(byte in[]);
5 | }
6 |
--------------------------------------------------------------------------------
/ijk/src/main/java/tv/danmaku/ijk/media/player/misc/IAndroidIO.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Bilibili
3 | * Copyright (C) 2016 Raymond Zheng
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.misc;
19 |
20 | import java.io.IOException;
21 |
22 | @SuppressWarnings("RedundantThrows")
23 | public interface IAndroidIO {
24 | int open(String url) throws IOException;
25 | int read(byte[] buffer, int size) throws IOException;
26 | long seek(long offset, int whence) throws IOException;
27 | int close() throws IOException;
28 | }
29 |
--------------------------------------------------------------------------------
/ijk/src/main/java/tv/danmaku/ijk/media/player/misc/IMediaDataSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Bilibili
3 | * Copyright (C) 2015 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.misc;
19 |
20 | import java.io.IOException;
21 |
22 | @SuppressWarnings("RedundantThrows")
23 | public interface IMediaDataSource {
24 | int readAt(long position, byte[] buffer, int offset, int size) throws IOException;
25 |
26 | long getSize() throws IOException;
27 |
28 | void close() throws IOException;
29 | }
30 |
--------------------------------------------------------------------------------
/ijk/src/main/java/tv/danmaku/ijk/media/player/misc/IMediaFormat.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Bilibili
3 | * Copyright (C) 2015 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.misc;
19 |
20 | public interface IMediaFormat {
21 | // Common keys
22 | String KEY_MIME = "mime";
23 |
24 | // Video Keys
25 | String KEY_WIDTH = "width";
26 | String KEY_HEIGHT = "height";
27 |
28 | String getString(String name);
29 |
30 | int getInteger(String name);
31 | }
32 |
--------------------------------------------------------------------------------
/ijk/src/main/java/tv/danmaku/ijk/media/player/misc/ITrackInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Bilibili
3 | * Copyright (C) 2015 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.misc;
19 |
20 | public interface ITrackInfo {
21 | int MEDIA_TRACK_TYPE_AUDIO = 2;
22 | int MEDIA_TRACK_TYPE_METADATA = 5;
23 | int MEDIA_TRACK_TYPE_SUBTITLE = 4;
24 | int MEDIA_TRACK_TYPE_TIMEDTEXT = 3;
25 | int MEDIA_TRACK_TYPE_UNKNOWN = 0;
26 | int MEDIA_TRACK_TYPE_VIDEO = 1;
27 |
28 | IMediaFormat getFormat();
29 |
30 | String getLanguage();
31 |
32 | int getTrackType();
33 |
34 | String getInfoInline();
35 | }
36 |
--------------------------------------------------------------------------------
/ijk/src/main/java/tv/danmaku/ijk/media/player/pragma/Pragma.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Bilibili
3 | * Copyright (C) 2013 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package tv.danmaku.ijk.media.player.pragma;
18 |
19 | /*-
20 | * configurated by app project
21 | */
22 | public class Pragma {
23 | public static final boolean ENABLE_VERBOSE = true;
24 | }
25 |
--------------------------------------------------------------------------------
/ijk/src/main/jniLibs/arm64-v8a/libijkffmpeg.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/ijk/src/main/jniLibs/arm64-v8a/libijkffmpeg.so
--------------------------------------------------------------------------------
/ijk/src/main/jniLibs/arm64-v8a/libijkplayer.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/ijk/src/main/jniLibs/arm64-v8a/libijkplayer.so
--------------------------------------------------------------------------------
/ijk/src/main/jniLibs/arm64-v8a/libijksdl.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/ijk/src/main/jniLibs/arm64-v8a/libijksdl.so
--------------------------------------------------------------------------------
/ijk/src/main/jniLibs/armeabi-v7a/libijkffmpeg.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/ijk/src/main/jniLibs/armeabi-v7a/libijkffmpeg.so
--------------------------------------------------------------------------------
/ijk/src/main/jniLibs/armeabi-v7a/libijkplayer.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/ijk/src/main/jniLibs/armeabi-v7a/libijkplayer.so
--------------------------------------------------------------------------------
/ijk/src/main/jniLibs/armeabi-v7a/libijksdl.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/ijk/src/main/jniLibs/armeabi-v7a/libijksdl.so
--------------------------------------------------------------------------------
/ijk/src/main/jniLibs/armeabi/libijkffmpeg.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/ijk/src/main/jniLibs/armeabi/libijkffmpeg.so
--------------------------------------------------------------------------------
/ijk/src/main/jniLibs/armeabi/libijkplayer.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/ijk/src/main/jniLibs/armeabi/libijkplayer.so
--------------------------------------------------------------------------------
/ijk/src/main/jniLibs/armeabi/libijksdl.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/ijk/src/main/jniLibs/armeabi/libijksdl.so
--------------------------------------------------------------------------------
/ijk/src/main/jniLibs/x86/libijkffmpeg.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/ijk/src/main/jniLibs/x86/libijkffmpeg.so
--------------------------------------------------------------------------------
/ijk/src/main/jniLibs/x86/libijkplayer.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/ijk/src/main/jniLibs/x86/libijkplayer.so
--------------------------------------------------------------------------------
/ijk/src/main/jniLibs/x86/libijksdl.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/ijk/src/main/jniLibs/x86/libijksdl.so
--------------------------------------------------------------------------------
/ijk/src/main/jniLibs/x86_64/libijkffmpeg.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/ijk/src/main/jniLibs/x86_64/libijkffmpeg.so
--------------------------------------------------------------------------------
/ijk/src/main/jniLibs/x86_64/libijkplayer.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/ijk/src/main/jniLibs/x86_64/libijkplayer.so
--------------------------------------------------------------------------------
/ijk/src/main/jniLibs/x86_64/libijksdl.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/ijk/src/main/jniLibs/x86_64/libijksdl.so
--------------------------------------------------------------------------------
/iplayer/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /iplayer.gradle
--------------------------------------------------------------------------------
/iplayer/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | //应用打包配置
3 | //apply from: 'iplayer.gradle'
4 | //发布到jitpack应用配置
5 | apply plugin: 'com.github.dcendents.android-maven'
6 | group='com.github.hty527'//xxx:代表你的github用户名
7 |
8 | android {
9 | compileSdkVersion 30
10 | buildToolsVersion "30.0.2"
11 |
12 | defaultConfig {
13 | minSdkVersion 16
14 | //noinspection ExpiredTargetSdkVersion
15 | targetSdkVersion 30
16 | versionCode rootProject.ext.sdk.versionCode
17 | versionName rootProject.ext.sdk.versionName
18 | }
19 | lintOptions {
20 | abortOnError false
21 | }
22 | }
23 |
24 | //下列注释配置被apply from: 'iplayer.gradle'替换 配置模块未本地Maven仓库
25 | //uploadArchives{
26 | // repositories.mavenDeployer{
27 | // // 配置本地仓库路径,这里是项目的根目录下的maven目录中
28 | // repository(url: uri('../maven'))
29 | // // 唯一标识 一般为模块包名 也可其他
30 | // pom.groupId = rootProject.ext.groupId
31 | // // 项目名称(一般为模块名称 也可其他
32 | // pom.artifactId = rootProject.ext.artifactId
33 | // // 发布的版本号
34 | // pom.version = rootProject.ext.version
35 | // }
36 | //}
37 |
38 | // 打包源码jar
39 | task sourcesJar(type: Jar) {
40 | from android.sourceSets.main.java.srcDirs
41 | archiveClassifier = 'sources'
42 | }
43 |
44 | dependencies {
45 | implementation fileTree(dir: "libs", include: ["*.jar"])
46 | }
--------------------------------------------------------------------------------
/iplayer/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 | #资源ID过滤
23 | -keep public class com.android.iplayer.R$*{
24 | public static final int *;
25 | }
26 | #保持自定义控件类不被混淆
27 | -keepclasseswithmembers class * {
28 | public (android.content.Context, android.util.AttributeSet);
29 | }
30 | #保持自定义控件类不被混淆
31 | -keepclasseswithmembers class * {
32 | public (android.content.Context, android.util.AttributeSet, int);
33 | }
--------------------------------------------------------------------------------
/iplayer/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/iplayer/src/main/java/com/android/iplayer/base/AbstractMediaPlayer.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.base;
2 |
3 | import android.content.Context;
4 | import com.android.iplayer.media.IMediaPlayer;
5 | import com.android.iplayer.listener.OnMediaEventListener;
6 |
7 | /**
8 | * created by hty
9 | * 2022/6/28
10 | * Desc:多媒体解码器基类,自定义多媒体解码器必须继承此类重写&&赋值所关心的监听器
11 | * 1、自定义解码器实现请参考com.android.iplayer.media.core.MediaPlayer类
12 | * 2、所有子类必须将OnMediaEventListener事件回调给mListener
13 | */
14 | public abstract class AbstractMediaPlayer implements IMediaPlayer {
15 |
16 | protected final String TAG = AbstractMediaPlayer.class.getSimpleName();
17 | protected Context mContext ;
18 | protected OnMediaEventListener mListener;//播放器监听器
19 |
20 | public AbstractMediaPlayer(Context context){
21 | this.mContext=context;
22 | }
23 |
24 | protected Context getContext() {
25 | return mContext;
26 | }
27 |
28 | @Override
29 | public void setMediaEventListener(OnMediaEventListener listener) {
30 | this.mListener=listener;
31 | }
32 |
33 | @Override
34 | public void release() {
35 | mListener=null;
36 | }
37 | }
--------------------------------------------------------------------------------
/iplayer/src/main/java/com/android/iplayer/interfaces/IBasePlayer.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.interfaces;
2 |
3 | import android.content.Context;
4 | import com.android.iplayer.base.AbstractMediaPlayer;
5 | import com.android.iplayer.base.BasePlayer;
6 | import com.android.iplayer.model.PlayerState;
7 |
8 | /**
9 | * created by hty
10 | * 2022/7/3
11 | * Desc:解码器持有的播放器代理人
12 | */
13 | public interface IBasePlayer {
14 |
15 | /**
16 | * 返回播放器的上下文
17 | * @return
18 | */
19 | Context getContext();
20 |
21 | /**
22 | * 返回一个继承自AbstractMediaPlayer的播放器解码器
23 | * @return
24 | */
25 | AbstractMediaPlayer getMediaPlayer();
26 |
27 | /**
28 | * 返回一个实现了IRenderView接口的自定义画面渲染器
29 | * @return 画面渲染器实体类
30 | */
31 | IRenderView getRenderView();
32 |
33 | /**
34 | * 宿主返回一个装载视频播放器的容器
35 | * @return
36 | */
37 | BasePlayer getVideoPlayer();
38 |
39 | /**
40 | * 播放内部各种事件
41 | * @param state 播放器内部状态
42 | * @param message 状态说明
43 | */
44 | void onPlayerState(PlayerState state, final String message);
45 |
46 | /**
47 | * 缓冲进度 主线程回调
48 | * @param percent 百分比
49 | */
50 | void onBuffer(int percent);
51 |
52 | /**
53 | * 视频宽高
54 | * @param width 视频宽
55 | * @param height 视频高
56 | */
57 | void onVideoSizeChanged(int width, int height);
58 |
59 | /**
60 | * 播放进度 主线程回调
61 | * @param currentDurtion 当前播放位置,单位:总进度的毫秒进度
62 | * @param totalDurtion 总时长,单位:毫秒
63 | */
64 | void onProgress(long currentDurtion, long totalDurtion);
65 | }
--------------------------------------------------------------------------------
/iplayer/src/main/java/com/android/iplayer/interfaces/IGestureControl.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.interfaces;
2 |
3 | /**
4 | * created by hty
5 | * 2022/8/5
6 | * Desc:如果你的自定义UI交互组件还需要处理手势交互,则需要实现此接口
7 | * 1、你的控制器需要继承GestureController
8 | * 2、你的自定义UI交互组件除了需要继承BaseControlWidget外还需要实现IGestureControl接口,你的ViewGroup才会收到此接口的回调
9 | */
10 | public interface IGestureControl {
11 |
12 | /**
13 | * 开始滑动
14 | */
15 | void onStartSlide();
16 |
17 | /**
18 | * 结束滑动
19 | */
20 | void onStopSlide();
21 |
22 | /**
23 | * 滑动调整进度
24 | * @param slidePosition 滑动进度
25 | * @param currentPosition 当前播放进度
26 | * @param duration 视频总长度
27 | */
28 | void onPositionChange(int slidePosition, int currentPosition, int duration);
29 |
30 | /**
31 | * 滑动调整亮度
32 | * @param percent 亮度百分比
33 | */
34 | void onBrightnessChange(int percent);
35 |
36 | /**
37 | * 滑动调整音量
38 | * @param percent 音量百分比
39 | */
40 | void onVolumeChange(int percent);
41 | }
--------------------------------------------------------------------------------
/iplayer/src/main/java/com/android/iplayer/interfaces/IRenderView.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.interfaces;
2 |
3 | import android.view.View;
4 | import com.android.iplayer.base.AbstractMediaPlayer;
5 |
6 | /**
7 | * created by hty
8 | * 2022/9/1
9 | * Desc:如需实现自定义画面渲染器,请实现此接口
10 | */
11 | public interface IRenderView {
12 |
13 | /**
14 | * 绑定解码器
15 | * @param mediaPlayer 绑定解码器 解码器
16 | */
17 | void attachMediaPlayer(AbstractMediaPlayer mediaPlayer);
18 |
19 | /**
20 | * 返回TextureView或SurfaceView
21 | * @return
22 | */
23 | View getView();
24 |
25 | /**
26 | * 视频的宽高更新
27 | * @param width 视频的宽更新,单位:分辨率像素
28 | * @param height 视频的高更新,单位:分辨率像素
29 | */
30 | void setVideoSize(int width,int height);
31 |
32 | /**
33 | * 画面缩放或裁剪模式,请参阅IMediaPlayer类中定义的常量值
34 | * @param zoomMode 画面缩放或裁剪模式,请参阅IMediaPlayer类中定义的常量值
35 | */
36 | void setZoomMode(int zoomMode);
37 |
38 | /**
39 | * 设置视频画面旋转角度
40 | * @param degree 旋转角度
41 | */
42 | void setDegree(int degree);
43 |
44 | /**
45 | * 设置View旋转角度
46 | * @param rotation 旋转角度
47 | */
48 | void setViewRotation(int rotation);
49 |
50 | /**
51 | * 设置画面比例
52 | * @param sarNum 设置画面比例,比例x
53 | * @param sarDen 设置画面比例,比例y
54 | */
55 | void setSarSize(int sarNum,int sarDen);
56 |
57 | /**
58 | * 设置画面镜像旋转
59 | * @param mirror 设置画面镜像旋转 true:画面翻转 false:正常
60 | * @return true:画面翻转 false:正常
61 | */
62 | boolean setMirror(boolean mirror);
63 |
64 | /**
65 | * 开启、关闭画面镜像旋转
66 | * @return 是否镜像,true:镜像音 false:正常
67 | */
68 | boolean toggleMirror();
69 |
70 | /**
71 | * 请求重绘布局
72 | */
73 | void requestDrawLayout();
74 |
75 | /**
76 | * 释放画面渲染器
77 | */
78 | void release();
79 | }
--------------------------------------------------------------------------------
/iplayer/src/main/java/com/android/iplayer/listener/OnMediaEventListener.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.listener;
2 |
3 | import com.android.iplayer.media.IMediaPlayer;
4 |
5 | /**
6 | * created by hty
7 | * 2022/9/1
8 | * Desc:播放器内部各种事件回调
9 | */
10 | public interface OnMediaEventListener {
11 |
12 | /**
13 | * 播放器异步准备好了
14 | * @param mp 播放器
15 | */
16 | void onPrepared(IMediaPlayer mp);
17 |
18 | /**
19 | * 播放器缓冲进度
20 | * @param mp 播放器
21 | * @param percent 缓冲进度,单位:百分比
22 | */
23 | void onBufferUpdate(IMediaPlayer mp, int percent);
24 |
25 | /**
26 | * seek跳转播放成功
27 | * @param mp 播放器
28 | */
29 | void onSeekComplete(IMediaPlayer mp);
30 |
31 | /**
32 | * 视频的宽高发生变化
33 | * @param mp 播放器
34 | * @param width 视频宽,单位:分辨率
35 | * @param height 视频高,单位:分辨率
36 | * @param sar_num 视频比例X
37 | * @param sar_den 视频比例Y
38 | */
39 | void onVideoSizeChanged(IMediaPlayer mp, int width, int height, int sar_num, int sar_den);
40 |
41 | /**
42 | * 消息监听器,会将关于播放器的消息告知开发者,例如:视频渲染、音频渲染等
43 | * @param mp 播放器
44 | * @param what code码
45 | * @param extra 角度等其它参数
46 | * @return
47 | */
48 | boolean onInfo(IMediaPlayer mp, int what, int extra);
49 |
50 | /**
51 | * 播放完成,仅当setLoop为false回调
52 | * @param mp 播放器
53 | */
54 | void onCompletion(IMediaPlayer mp);
55 |
56 | /**
57 | * 错误监听器,播放器遇到错误时会将相应的错误码通过此回调接口告知开发者
58 | * @param mp 播放器
59 | * @param what 错误码
60 | * @param extra 错误信息
61 | * @return
62 | */
63 | boolean onError(IMediaPlayer mp, int what, int extra);
64 | }
--------------------------------------------------------------------------------
/iplayer/src/main/java/com/android/iplayer/listener/OnPlayerEventListener.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.listener;
2 |
3 | import com.android.iplayer.base.AbstractMediaPlayer;
4 | import com.android.iplayer.interfaces.IRenderView;
5 | import com.android.iplayer.model.PlayerState;
6 |
7 | /**
8 | * created by hty
9 | * 2022/6/28
10 | * Desc:简单的播放器内部事件回调,提供给播放器容器的宿主实现监听
11 | */
12 | public abstract class OnPlayerEventListener {
13 | /**
14 | * 如需自定义解码器,可复写此方法并返回一个继承自AbstractMediaPlayer的自定义多媒体解码器,如果返回为空,则适用内部默认的DefaultMediaPlayer解码器
15 | * @return 一个自定义的多媒体解码器
16 | */
17 | public AbstractMediaPlayer createMediaPlayer(){return null;}
18 |
19 | /**
20 | * 如需自定义解码器,可复写此方法并返回一个实现了IRenderView接口的自定义画面渲染器,如果返回为空,则适用内部默认的MediaTextureView解码器
21 | * @return
22 | */
23 | public IRenderView createRenderView(){return null;}
24 |
25 | /**
26 | * 播放器内部各状态
27 | * @param state 状态请参考PlayerState中定义的状态
28 | * @param message 状态描述
29 | */
30 | public void onPlayerState(PlayerState state,String message){}
31 |
32 | /**
33 | * 视频宽高
34 | * @param width 视频宽
35 | * @param height 视频高
36 | */
37 | public void onVideoSizeChanged(int width, int height){}
38 |
39 | /**
40 | * 播放进度实时回调,回调到主线程
41 | * @param currentDurtion 当前播放进度,单位:毫秒时间戳
42 | * @param totalDurtion 总时长,单位:毫秒时间戳
43 | */
44 | public void onProgress(long currentDurtion, long totalDurtion) {}
45 |
46 | /**
47 | * @param isMute 当静音状态发生了变化回调,true:处于静音状态 false:处于非静音状态
48 | */
49 | public void onMute(boolean isMute) {}
50 |
51 | /**
52 | * @param isMirror 当播放器的内部画面渲染镜像状态发生了变化回调, true:处于镜像状态 false:处于非镜像状态
53 | */
54 | public void onMirror(boolean isMirror) {}
55 |
56 | /**
57 | * @param zoomModel 当播放器内部渲染缩放模式发生了变化回调,,当初始化和播放器缩放模式设置发生变化时回调,参考IMediaPlayer类
58 | */
59 | public void onZoomModel(int zoomModel) {}
60 | }
--------------------------------------------------------------------------------
/iplayer/src/main/java/com/android/iplayer/listener/OnWindowActionListener.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.listener;
2 |
3 | import com.android.iplayer.base.BasePlayer;
4 |
5 | /**
6 | * created by hty
7 | * 2022/7/4
8 | * Desc:全局的悬浮窗窗口播放器关闭\点击事件监听器
9 | */
10 | public interface OnWindowActionListener {
11 |
12 | /**
13 | * 持续移动中
14 | * @param x
15 | * @param y
16 | */
17 | void onMovie(float x,float y);
18 |
19 | /**
20 | * 点击悬浮窗回调
21 | * @param basePlayer 播放器实例
22 | * @param customParams 自定义参数
23 | */
24 | void onClick(BasePlayer basePlayer,Object customParams);
25 |
26 |
27 | /**
28 | * 关闭事件
29 | */
30 | void onClose();
31 | }
--------------------------------------------------------------------------------
/iplayer/src/main/java/com/android/iplayer/manager/IVideoManager.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.manager;
2 |
3 | /**
4 | * created by hty
5 | * 2022/7/3
6 | * Desc:播放器内部的公共设置等
7 | */
8 | public final class IVideoManager {
9 |
10 | private volatile static IVideoManager mInstance;
11 | //是否支持在4G环境下播放
12 | private boolean mIsMobileNetwork;
13 | //是否监听并处理音频焦点事件?
14 | private boolean mInterceptTAudioFocus;//true:拦截,并在收到音频焦点失去后暂停播放 false:什么也不处理
15 |
16 | //调用入口
17 | public static synchronized IVideoManager getInstance() {
18 | synchronized (IVideoManager.class) {
19 | if (null == mInstance) {
20 | mInstance = new IVideoManager();
21 | }
22 | }
23 | return mInstance;
24 | }
25 |
26 | /**
27 | * 是否支持4G网络播放
28 | * @param mobileNetwork
29 | */
30 | public IVideoManager setMobileNetwork(boolean mobileNetwork) {
31 | mIsMobileNetwork = mobileNetwork;
32 | return mInstance;
33 | }
34 |
35 | public boolean isMobileNetwork() {
36 | return mIsMobileNetwork;
37 | }
38 |
39 | /**
40 | * 是否监听并处理音频焦点事件
41 | * @return true:拦截,并在收到音频焦点失去后暂停播放 false:什么也不处理
42 | */
43 | public boolean isInterceptTAudioFocus() {
44 | return mInterceptTAudioFocus;
45 | }
46 |
47 | /**
48 | * 是否监听并处理音频焦点事件
49 | * @param interceptTAudioFocus true:拦截,并在收到音频焦点失去后暂停播放 false:什么也不处理
50 | */
51 | public IVideoManager setInterceptTAudioFocus(boolean interceptTAudioFocus) {
52 | mInterceptTAudioFocus = interceptTAudioFocus;
53 | return mInstance;
54 | }
55 | }
--------------------------------------------------------------------------------
/iplayer/src/main/java/com/android/iplayer/media/MediaFactory.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.media;
2 |
3 | import android.content.Context;
4 | import com.android.iplayer.base.AbstractMediaPlayer;
5 |
6 | /**
7 | * created by hty
8 | * 2022/9/15
9 | * Desc:所有解码器的工厂构造可继承此类来实现创建自己的解码器
10 | */
11 | public abstract class MediaFactory {
12 |
13 | /**
14 | * 构造播放器解码器
15 | * @param context 上下文
16 | * @return 继承自AbstractMediaPlayer的解码器
17 | */
18 | public abstract M createPlayer(Context context);
19 | }
--------------------------------------------------------------------------------
/iplayer/src/main/java/com/android/iplayer/media/core/MediaPlayerFactory.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.media.core;
2 |
3 | import android.content.Context;
4 | import com.android.iplayer.media.MediaFactory;
5 |
6 | /**
7 | * created by hty
8 | * 2022/9/15
9 | * Desc:系统MediaPlayer的工厂类,{@link MediaPlayer}
10 | */
11 | public class MediaPlayerFactory extends MediaFactory {
12 |
13 | public static MediaPlayerFactory create() {
14 | return new MediaPlayerFactory();
15 | }
16 |
17 | @Override
18 | public MediaPlayer createPlayer(Context context) {
19 | return new MediaPlayer(context);
20 | }
21 | }
--------------------------------------------------------------------------------
/iplayer/src/main/java/com/android/iplayer/model/PlayerState.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.model;
2 |
3 | /**
4 | * created by hty
5 | * 2022/6/28
6 | * Desc:播放器内部事件
7 | */
8 | public enum PlayerState {
9 | STATE_RESET,//初始状态\播放器还原重置
10 | STATE_PREPARE,//准备中
11 | STATE_BUFFER,//缓冲中
12 | STATE_START,//开始首帧播放
13 | STATE_ON_PAUSE,//生命周期暂停
14 | STATE_PAUSE,//人为暂停
15 | STATE_PLAY,//缓冲结束后恢复播放
16 | STATE_ON_PLAY,//生命周期恢复播放
17 | STATE_STOP,//停止播放
18 | STATE_COMPLETION,//播放已完成
19 | STATE_MOBILE,//移动网络环境下
20 | STATE_ERROR,//错误
21 | STATE_DESTROY//播放器回收
22 | }
--------------------------------------------------------------------------------
/iplayer/src/main/java/com/android/iplayer/utils/ILogger.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.utils;
2 |
3 | import android.util.Log;
4 | import com.android.iplayer.BuildConfig;
5 |
6 | /**
7 | * created by hty
8 | * 2022/6/28
9 | * Desc:
10 | */
11 | public class ILogger {
12 |
13 | public static boolean DEBUG = true;
14 |
15 | public static void setDebug(boolean debug){
16 | DEBUG=debug;
17 | }
18 |
19 | public static String getVersion(){
20 | return BuildConfig.VERSION_NAME;
21 | }
22 |
23 | public static void pd(String TAG, String message){
24 | if(DEBUG){
25 | Log.println(Log.DEBUG,TAG,message);
26 | }
27 | }
28 |
29 | public static void pe(String TAG, String message){
30 | if(DEBUG){
31 | Log.println(Log.ERROR,TAG,message);
32 | }
33 | }
34 |
35 | public static void pw(String TAG, String message){
36 | if(DEBUG){
37 | Log.println(Log.WARN,TAG,message);
38 | }
39 | }
40 |
41 | public static void pi(String TAG, String message){
42 | if(DEBUG){
43 | Log.println(Log.INFO,TAG,message);
44 | }
45 | }
46 | public static void d(String TAG, String message) {
47 | if(DEBUG){
48 | Log.d(TAG,message);
49 | }
50 | }
51 |
52 | public static void e(String TAG, String message) {
53 | if(DEBUG){
54 | Log.e(TAG,message);
55 | }
56 | }
57 |
58 | public static void v(String TAG, String message) {
59 | if(DEBUG){
60 | Log.e(TAG,message);
61 | }
62 | }
63 |
64 | public static void w(String TAG, String message) {
65 | if(DEBUG){
66 | Log.w(TAG,message);
67 | }
68 | }
69 |
70 | public static void i(String TAG, String message) {
71 | if(DEBUG){
72 | Log.i(TAG,message);
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/iplayer/src/main/java/com/android/iplayer/widget/VideoPlayer.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.widget;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import com.android.iplayer.base.BasePlayer;
6 | import com.android.iplayer.controller.VideoController;
7 |
8 | /**
9 | * created by hty
10 | * 2022/6/22
11 | * desc:这是一个播放器的实现类,内部封装了如何使用SDK提供的交互组件的调用示例
12 | * 1、需要功能自定义,请复写父类的方法修改
13 | * 2、此播放器提供使用默认控制器作为播放器控制器方法,请调用:{@link #initController()}
14 | * 3、如需使用默认UI交互,需集成implementation 'com.github.hty527.iPlayer:widget:lastversion'后,使用WidgetFactory.bindDefaultControls(controller);将UI交互组件绑定到控制器。
15 | */
16 | public class VideoPlayer extends BasePlayer {
17 |
18 | public VideoPlayer(Context context) {
19 | super(context);
20 | }
21 |
22 | public VideoPlayer(Context context, AttributeSet attrs) {
23 | super(context, attrs);
24 | }
25 |
26 | public VideoPlayer(Context context, AttributeSet attrs, int defStyleAttr) {
27 | super(context, attrs, defStyleAttr);
28 | }
29 |
30 | @Override
31 | protected void initViews() {}
32 |
33 | /**
34 | * 绑定默认的控制器到播放器
35 | * @return
36 | */
37 | public VideoController initController(){
38 | VideoController controller = new VideoController(getContext());
39 | setController(controller);
40 | return controller;
41 | }
42 | }
--------------------------------------------------------------------------------
/iplayer/src/main/java/com/android/iplayer/widget/view/LayoutProvider.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.widget.view;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.graphics.Outline;
5 | import android.view.View;
6 | import android.view.ViewOutlineProvider;
7 |
8 | /**
9 | * created by hty
10 | * 2022/6/30
11 | * Desc:View圆角设置
12 | */
13 | @SuppressLint("NewApi")
14 | public class LayoutProvider extends ViewOutlineProvider {
15 |
16 | private float mRadius;
17 |
18 | public LayoutProvider(float radius){
19 | this.mRadius = radius;
20 | }
21 |
22 | @Override
23 | public void getOutline(View view, Outline outline) {
24 | outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), mRadius);
25 | view.setClipToOutline(true);
26 | }
27 | }
--------------------------------------------------------------------------------
/iplayer/src/main/java/com/android/iplayer/widget/view/ScreenOrientationRotate.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.widget.view;
2 |
3 | import android.content.Context;
4 | import android.view.OrientationEventListener;
5 |
6 | /**
7 | * created by hty
8 | * 2022/9/15
9 | * Desc:监听屏幕四个角度变化
10 | */
11 | public class ScreenOrientationRotate extends OrientationEventListener {
12 |
13 | private long mLastTime;
14 | private OnDisplayOrientationListener mOnDisplayOrientationListener;
15 |
16 | public ScreenOrientationRotate(Context context) {
17 | super(context);
18 | }
19 |
20 | @Override
21 | public void onOrientationChanged(int orientation) {
22 | long currentTimeMillis = System.currentTimeMillis();
23 | //500毫秒检测一次
24 | if(currentTimeMillis-mLastTime<500){
25 | return;
26 | }
27 | if(null!=mOnDisplayOrientationListener) mOnDisplayOrientationListener.onOrientationChanged(orientation);
28 | mLastTime=currentTimeMillis;
29 | }
30 |
31 | public void setOnDisplayOrientationListener(OnDisplayOrientationListener onDisplayOrientationListener) {
32 | mOnDisplayOrientationListener = onDisplayOrientationListener;
33 | }
34 |
35 | public interface OnDisplayOrientationListener {
36 | void onOrientationChanged(int angle);
37 | }
38 |
39 | public void onReset(){
40 | mOnDisplayOrientationListener =null;
41 | }
42 | }
--------------------------------------------------------------------------------
/iplayer/src/main/res/anim/window_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
9 |
--------------------------------------------------------------------------------
/iplayer/src/main/res/anim/window_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
9 |
--------------------------------------------------------------------------------
/iplayer/src/main/res/drawable/player_locker_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/iplayer/src/main/res/layout/player_base_video.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
11 |
15 |
--------------------------------------------------------------------------------
/iplayer/src/main/res/layout/player_video_controller.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
23 |
24 |
--------------------------------------------------------------------------------
/iplayer/src/main/res/layout/player_window_float.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
16 |
17 |
24 |
25 |
--------------------------------------------------------------------------------
/iplayer/src/main/res/mipmap-xxhdpi/ic_player_locker_false.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/iplayer/src/main/res/mipmap-xxhdpi/ic_player_locker_false.png
--------------------------------------------------------------------------------
/iplayer/src/main/res/mipmap-xxhdpi/ic_player_locker_true.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/iplayer/src/main/res/mipmap-xxhdpi/ic_player_locker_true.png
--------------------------------------------------------------------------------
/iplayer/src/main/res/mipmap-xxhdpi/ic_player_window_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/iplayer/src/main/res/mipmap-xxhdpi/ic_player_window_close.png
--------------------------------------------------------------------------------
/iplayer/src/main/res/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 未申明和获取悬浮窗权限
3 | 已解锁
4 | 已锁定
5 | 解码器内核:
6 | 渲染器内核:
7 | 播放完成
8 | 首帧渲染
9 | 缓冲开始
10 | 缓冲结束
11 | 快进快退恢复播放
12 | 播放失败,播放链接超时
13 | 播放失败,不支持的视频文件格式
14 | 播放失败,链接DNS失败
15 | 播放失败,请检查视频文件地址有效性
16 | 视频解码失败
17 | 播放地址为空,请检查!
18 | 网络未连接
19 | 移动网络播放
20 | 播放准备中
21 | 播放失败,error:
22 | 恢复播放
23 | 暂停播放
24 | 停止播放
25 | 结束播放并重置
26 | 播放器销毁
27 |
--------------------------------------------------------------------------------
/iplayer/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/iplayer/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':cache'
2 | include ':app'
3 | include ':iplayer'
4 | include ':ijk'
5 | include ':exo'
6 | include ':widget'
7 | rootProject.name = "iPlayer"
--------------------------------------------------------------------------------
/widget/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/widget/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | //发布到jitpack应用配置
3 | apply plugin: 'com.github.dcendents.android-maven'
4 | group='com.github.hty527'//xxx:代表你的github用户名
5 |
6 | android {
7 | compileSdkVersion 30
8 | buildToolsVersion "30.0.2"
9 |
10 | defaultConfig {
11 | minSdkVersion 16
12 | //noinspection ExpiredTargetSdkVersion
13 | targetSdkVersion 30
14 | versionCode rootProject.ext.sdk.versionCode
15 | versionName rootProject.ext.sdk.versionName
16 | }
17 | lintOptions {
18 | abortOnError false
19 | }
20 | }
21 |
22 | // 打包源码jar
23 | task sourcesJar(type: Jar) {
24 | from android.sourceSets.main.java.srcDirs
25 | archiveClassifier = 'sources'
26 | }
27 |
28 | dependencies {
29 | implementation fileTree(dir: "libs", include: ["*.jar"])
30 | //播放器
31 | implementation project(':iplayer')
32 | }
--------------------------------------------------------------------------------
/widget/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 | #资源ID过滤
24 | -keep public class com.android.iplayer.widget.R$*{
25 | public static final int *;
26 | }
27 | #保持自定义控件类不被混淆
28 | -keepclasseswithmembers class * {
29 | public (android.content.Context, android.util.AttributeSet);
30 | }
31 | #保持自定义控件类不被混淆
32 | -keepclasseswithmembers class * {
33 | public (android.content.Context, android.util.AttributeSet, int);
34 | }
--------------------------------------------------------------------------------
/widget/src/androidTest/java/com/android/iplayer/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer;
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 | assertEquals("com.android.iplayer.test", appContext.getPackageName());
25 | }
26 | }
--------------------------------------------------------------------------------
/widget/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/widget/src/main/java/com/android/iplayer/widget/controls/ControlCompletionView.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer.widget.controls;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import com.android.iplayer.widget.R;
6 | import com.android.iplayer.base.BaseControlWidget;
7 | import com.android.iplayer.model.PlayerState;
8 |
9 | /**
10 | * created by hty
11 | * 2022/8/22
12 | * Desc:UI控制器-播放完成
13 | */
14 | public class ControlCompletionView extends BaseControlWidget {
15 |
16 | public ControlCompletionView(Context context) {
17 | super(context);
18 | }
19 |
20 | @Override
21 | public int getLayoutId() {
22 | return R.layout.player_control_completion;
23 | }
24 |
25 | @Override
26 | public void initViews() {
27 | hide();
28 | setOnClickListener(new OnClickListener() {
29 | @Override
30 | public void onClick(View view) {
31 | if(null!=mControlWrapper) mControlWrapper.togglePlay();
32 | }
33 | });
34 | }
35 |
36 | @Override
37 | public void onPlayerState(PlayerState state, String message) {
38 | switch (state) {
39 | case STATE_COMPLETION://播放结束
40 | if(!isWindowScene()&&!isPreViewScene()){//窗口播放模式/试看模式不显示
41 | show();
42 | }
43 | break;
44 | default:
45 | hide();
46 | }
47 | }
48 |
49 | @Override
50 | public void onOrientation(int direction) {}
51 | }
--------------------------------------------------------------------------------
/widget/src/main/res/drawable/player_battery_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/widget/src/main/res/drawable/player_battery_line.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/widget/src/main/res/drawable/player_bg_bottom_controller.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/widget/src/main/res/drawable/player_bg_bottom_list_controller.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/widget/src/main/res/drawable/player_bg_btn_continue_play.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/widget/src/main/res/drawable/player_bottom_progress.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | -
19 |
20 |
21 |
22 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/widget/src/main/res/drawable/player_gesture_content_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/widget/src/main/res/drawable/player_gesture_content_portrait_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/widget/src/main/res/drawable/player_gesture_regulate_progress.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 | -
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/widget/src/main/res/drawable/player_progress_loading.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
12 |
17 |
18 |
--------------------------------------------------------------------------------
/widget/src/main/res/drawable/player_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 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/widget/src/main/res/drawable/player_seek_thumb.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/widget/src/main/res/drawable/player_surplus_time_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/widget/src/main/res/layout/player_base_video.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
11 |
15 |
--------------------------------------------------------------------------------
/widget/src/main/res/layout/player_control_completion.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
--------------------------------------------------------------------------------
/widget/src/main/res/layout/player_control_loading.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
21 |
28 |
29 |
--------------------------------------------------------------------------------
/widget/src/main/res/layout/player_control_status.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
26 |
39 |
--------------------------------------------------------------------------------
/widget/src/main/res/layout/player_video_controller.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
23 |
24 |
--------------------------------------------------------------------------------
/widget/src/main/res/layout/player_window_float.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
29 |
30 |
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_back.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_battery_in.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_battery_in.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_brightness.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_brightness.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_full_scrrent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_full_scrrent.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_gesture_last.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_gesture_last.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_gesture_next.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_gesture_next.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_locker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_locker.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_menu.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_menu_dlna.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_menu_dlna.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_menu_window.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_menu_window.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_mute_false.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_mute_false.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_mute_true.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_mute_true.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_pause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_pause.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_play.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_replay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_replay.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_shadow_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_shadow_bottom.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_shadow_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_shadow_top.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_sound.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_sound.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_sound_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_sound_off.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_start.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_start.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_window_full.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_window_full.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_window_pause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_window_pause.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_window_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_window_play.png
--------------------------------------------------------------------------------
/widget/src/main/res/mipmap-xxhdpi/ic_player_window_replay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hty527/iPlayer/8d81703b36670d7f3c4f17c95e2d604b62f9c676/widget/src/main/res/mipmap-xxhdpi/ic_player_window_replay.png
--------------------------------------------------------------------------------
/widget/src/main/res/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 将使用流量播放,是否继续?
3 | 继续播放
4 | 试看结束
5 | 知道了
6 | 播放失败,点击重试播放
7 | 重试
8 | 未知原因
9 | 未知
10 |
--------------------------------------------------------------------------------
/widget/src/main/res/values/color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #1DBA5B
4 | #CC1DBA5B
5 | #00000000
6 | #00000000
7 | #FFFFFF
8 | #66000000
9 | #FFFFFF
10 | #33FFFFFF
11 | #37CAF9
12 | @color/player_style
13 |
--------------------------------------------------------------------------------
/widget/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 45dp
4 | 36dp
5 | 38dp
6 | 38dp
7 | 48dp
8 | 72dp
9 |
--------------------------------------------------------------------------------
/widget/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Try to play with traffic. Is it allowed?
3 | Allow to play
4 | Try to finish
5 | got it
6 | Play failed, click Retry to play
7 | retry
8 | Unknown reason
9 | unknown
10 |
--------------------------------------------------------------------------------
/widget/src/test/java/com/android/iplayer/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.android.iplayer;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------