├── .gitignore ├── README.md ├── README_C.md ├── README_E.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── playerview ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── dl7 │ │ └── player │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── dl7 │ │ │ └── player │ │ │ ├── danmaku │ │ │ ├── AcFunDanmakuParser.java │ │ │ ├── BaseDanmakuConverter.java │ │ │ ├── BaseDanmakuData.java │ │ │ ├── BiliDanmukuParser.java │ │ │ ├── DanmakuType.java │ │ │ ├── OnDanmakuListener.java │ │ │ └── VideoDanmakuSync.java │ │ │ ├── media │ │ │ ├── AdapterMediaQuality.java │ │ │ ├── AndroidMediaController.java │ │ │ ├── BaseListAdapter.java │ │ │ ├── FileMediaDataSource.java │ │ │ ├── IMediaController.java │ │ │ ├── IRenderView.java │ │ │ ├── IjkPlayerView.java │ │ │ ├── IjkVideoView.java │ │ │ ├── MeasureHelper.java │ │ │ ├── MediaPlayerCompat.java │ │ │ ├── MediaPlayerParams.java │ │ │ ├── MediaQualityInfo.java │ │ │ ├── SurfaceRenderView.java │ │ │ └── TextureRenderView.java │ │ │ ├── utils │ │ │ ├── AnimHelper.java │ │ │ ├── MotionEventUtils.java │ │ │ ├── NavUtils.java │ │ │ ├── NetWorkUtils.java │ │ │ ├── SDCardUtils.java │ │ │ ├── SoftInputUtils.java │ │ │ ├── StringUtils.java │ │ │ └── WindowUtils.java │ │ │ └── widgets │ │ │ ├── MarqueeTextView.java │ │ │ └── ShareDialog.java │ └── res │ │ ├── anim │ │ ├── dialog_zoom_in.xml │ │ └── dialog_zoom_out.xml │ │ ├── drawable │ │ ├── layer_battery_progress.xml │ │ ├── layer_seek_progress.xml │ │ ├── sel_btn_ar_16_9.xml │ │ ├── sel_btn_ar_4_3.xml │ │ ├── sel_btn_ar_adjust_screen.xml │ │ ├── sel_btn_ar_adjust_video.xml │ │ ├── sel_btn_danmaku_control.xml │ │ ├── sel_btn_danmaku_input_options_bottom_type.xml │ │ ├── sel_btn_danmaku_input_options_color.xml │ │ ├── sel_btn_danmaku_input_options_medium_textsize.xml │ │ ├── sel_btn_danmaku_input_options_rl_type.xml │ │ ├── sel_btn_danmaku_input_options_small_textsize.xml │ │ ├── sel_btn_danmaku_input_options_top_type.xml │ │ ├── sel_btn_fullscreen.xml │ │ ├── sel_btn_play.xml │ │ ├── sel_btn_share_left.xml │ │ ├── sel_btn_share_right.xml │ │ ├── sel_item_background.xml │ │ ├── sel_media_quality_border.xml │ │ ├── sel_media_quality_text.xml │ │ ├── sel_player_lock.xml │ │ ├── shape_dialog_border.xml │ │ ├── shape_player_lock_bg.xml │ │ ├── shape_seek_ball.xml │ │ ├── shape_selected_border.xml │ │ ├── shape_send_danmaku_bg.xml │ │ ├── shape_video_bg.xml │ │ └── transition_item_background.xml │ │ ├── layout │ │ ├── adapter_media_quality.xml │ │ ├── dialog_share.xml │ │ ├── layout_bottom_bar.xml │ │ ├── layout_danmaku_input_options.xml │ │ ├── layout_media_quality.xml │ │ ├── layout_player_view.xml │ │ ├── layout_send_danmaku.xml │ │ ├── layout_skip_tip.xml │ │ ├── layout_top_bar.xml │ │ └── layout_touch_gestures.xml │ │ ├── mipmap-hdpi │ │ ├── ic_battery.png │ │ ├── ic_battery_charging.png │ │ ├── ic_battery_red.png │ │ ├── ic_brightness.png │ │ ├── ic_cancel_danmaku.png │ │ ├── ic_cancel_skip.png │ │ ├── ic_danmaku_closed.png │ │ ├── ic_danmaku_open.png │ │ ├── ic_fast_forward.png │ │ ├── ic_fast_rewind.png │ │ ├── ic_fullscreen.png │ │ ├── ic_fullscreen_exit.png │ │ ├── ic_media_quality_bd.png │ │ ├── ic_media_quality_high.png │ │ ├── ic_media_quality_medium.png │ │ ├── ic_media_quality_smooth.png │ │ ├── ic_media_quality_super.png │ │ ├── ic_play_circle.png │ │ ├── ic_player_lock.png │ │ ├── ic_player_unlock.png │ │ ├── ic_return_back.png │ │ ├── ic_send_danmaku.png │ │ ├── ic_video_pause.png │ │ ├── ic_video_play.png │ │ ├── ic_video_screenshot.png │ │ ├── ic_volume_off.png │ │ └── ic_volume_on.png │ │ ├── mipmap-xhdpi │ │ ├── ic_ar_16_9_inside.png │ │ ├── ic_ar_16_9_inside_checked.png │ │ ├── ic_ar_4_3_inside.png │ │ ├── ic_ar_4_3_inside_checked.png │ │ ├── ic_ar_adjust_screen.png │ │ ├── ic_ar_adjust_screen_checked.png │ │ ├── ic_ar_adjust_video.png │ │ ├── ic_ar_adjust_video_checked.png │ │ ├── ic_brightness.png │ │ ├── ic_btn_danmaku_input_options_color_checked.png │ │ ├── ic_cancel_danmaku.png │ │ ├── ic_cancel_skip.png │ │ ├── ic_danmaku_closed.png │ │ ├── ic_danmaku_input_more_color.png │ │ ├── ic_danmaku_input_options_bottom_type.png │ │ ├── ic_danmaku_input_options_bottom_type_checked.png │ │ ├── ic_danmaku_input_options_medium_textsize.png │ │ ├── ic_danmaku_input_options_medium_textsize_checked.png │ │ ├── ic_danmaku_input_options_rl_type.png │ │ ├── ic_danmaku_input_options_rl_type_checked.png │ │ ├── ic_danmaku_input_options_small_textsize.png │ │ ├── ic_danmaku_input_options_small_textsize_checked.png │ │ ├── ic_danmaku_input_options_top_type.png │ │ ├── ic_danmaku_input_options_top_type_checked.png │ │ ├── ic_danmaku_open.png │ │ ├── ic_fast_forward.png │ │ ├── ic_fast_rewind.png │ │ ├── ic_fullscreen.png │ │ ├── ic_fullscreen_exit.png │ │ ├── ic_media_quality_bd.png │ │ ├── ic_media_quality_high.png │ │ ├── ic_media_quality_medium.png │ │ ├── ic_media_quality_smooth.png │ │ ├── ic_media_quality_super.png │ │ ├── ic_play_circle.png │ │ ├── ic_player_lock.png │ │ ├── ic_player_unlock.png │ │ ├── ic_reload.png │ │ ├── ic_return_back.png │ │ ├── ic_send_danmaku.png │ │ ├── ic_video_pause.png │ │ ├── ic_video_play.png │ │ ├── ic_video_screenshot.png │ │ ├── ic_volume_off.png │ │ └── ic_volume_on.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_brightness.png │ │ ├── ic_cancel_danmaku.png │ │ ├── ic_cancel_skip.png │ │ ├── ic_danmaku_closed.png │ │ ├── ic_danmaku_open.png │ │ ├── ic_fast_forward.png │ │ ├── ic_fast_rewind.png │ │ ├── ic_fullscreen.png │ │ ├── ic_fullscreen_exit.png │ │ ├── ic_media_quality_bd.png │ │ ├── ic_media_quality_high.png │ │ ├── ic_media_quality_medium.png │ │ ├── ic_media_quality_smooth.png │ │ ├── ic_media_quality_super.png │ │ ├── ic_play_circle.png │ │ ├── ic_player_lock.png │ │ ├── ic_player_unlock.png │ │ ├── ic_return_back.png │ │ ├── ic_send_danmaku.png │ │ ├── ic_video_pause.png │ │ ├── ic_video_play.png │ │ ├── ic_video_screenshot.png │ │ ├── ic_volume_off.png │ │ └── ic_volume_on.png │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── ids.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── dl7 │ └── player │ └── ExampleUnitTest.java ├── sample ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── dl7 │ │ └── playerdemo │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ ├── afun.json │ │ └── custom.json │ ├── java │ │ └── com │ │ │ └── dl7 │ │ │ └── playerdemo │ │ │ ├── CustomDanmakuActivity.java │ │ │ ├── IjkFullscreenActivity.java │ │ │ ├── IjkPlayerActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── SwitchVideoActivity.java │ │ │ ├── TestAspectActivity.java │ │ │ ├── adapter │ │ │ ├── BaseListAdapter.java │ │ │ └── ListAdapter.java │ │ │ ├── danmaku │ │ │ ├── DanmakuConverter.java │ │ │ ├── DanmakuData.java │ │ │ ├── DanmakuLoader.java │ │ │ ├── DanmakuParser.java │ │ │ └── JsonStrSource.java │ │ │ └── utils │ │ │ ├── AfunData.java │ │ │ ├── AssetsHelper.java │ │ │ └── GsonHelper.java │ └── res │ │ ├── drawable │ │ ├── shape_edit_bg.xml │ │ ├── v2_sel_btn_send.xml │ │ ├── v2_sel_btn_send_text.xml │ │ └── v2_shape_comment_border.xml │ │ ├── layout │ │ ├── activity_custom_danmaku.xml │ │ ├── activity_ijk_player.xml │ │ ├── activity_main.xml │ │ ├── activity_switch_video.xml │ │ ├── activity_test_aspect.xml │ │ └── adapter_list.xml │ │ ├── mipmap-hdpi │ │ └── ic_danmaku_send.png │ │ ├── mipmap-xhdpi │ │ └── ic_danmaku_send.png │ │ ├── mipmap-xxhdpi │ │ ├── bg_card.9.png │ │ ├── ic_launcher.png │ │ └── photo.jpg │ │ ├── mipmap-xxxhdpi │ │ └── ic_danmaku_send.png │ │ ├── raw │ │ └── bili.xml │ │ ├── values-v19 │ │ └── styles.xml │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── dl7 │ └── playerdemo │ └── ExampleUnitTest.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | /.idea/ 11 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | mavenCentral() 7 | } 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:2.2.2' 10 | classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' 11 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' 12 | 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | allprojects { 19 | repositories { 20 | jcenter() 21 | maven { url 'https://jitpack.io' } 22 | } 23 | } 24 | 25 | task clean(type: Delete) { 26 | delete rootProject.buildDir 27 | } 28 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Dec 28 10:00:20 PST 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /playerview/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /playerview/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'com.github.dcendents.android-maven' 3 | group='com.github.Rukey7' 4 | 5 | android { 6 | compileSdkVersion 24 7 | buildToolsVersion "24.0.2" 8 | 9 | defaultConfig { 10 | minSdkVersion 14 11 | targetSdkVersion 24 12 | versionCode 4 13 | versionName "1.0.3" 14 | 15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 16 | 17 | } 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | 25 | } 26 | 27 | dependencies { 28 | compile fileTree(dir: 'libs', include: ['*.jar']) 29 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 30 | exclude group: 'com.android.support', module: 'support-annotations' 31 | }) 32 | compile 'com.android.support:appcompat-v7:24.2.0' 33 | testCompile 'junit:junit:4.12' 34 | // ijkplayer 35 | compile 'tv.danmaku.ijk.media:ijkplayer-java:0.7.8.1' 36 | compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.7.8.1' 37 | // compile 'com.github.Rukey7:ijkplayer-armv7a:0.7.5' 38 | // Danmaku 39 | compile 'com.github.ctiao:DanmakuFlameMaster:0.6.2' 40 | } 41 | -------------------------------------------------------------------------------- /playerview/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in F:\WorkTools\Android\SDK/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /playerview/src/androidTest/java/com/dl7/player/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.dl7.playerview.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /playerview/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/danmaku/AcFunDanmakuParser.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.danmaku; 2 | 3 | import android.graphics.Color; 4 | 5 | import org.json.JSONArray; 6 | import org.json.JSONException; 7 | import org.json.JSONObject; 8 | 9 | import master.flame.danmaku.danmaku.model.BaseDanmaku; 10 | import master.flame.danmaku.danmaku.model.android.Danmakus; 11 | import master.flame.danmaku.danmaku.parser.BaseDanmakuParser; 12 | import master.flame.danmaku.danmaku.parser.android.JSONSource; 13 | import master.flame.danmaku.danmaku.util.DanmakuUtils; 14 | 15 | /** 16 | * Created by long on 2016/12/22. 17 | * A站弹幕解析器 18 | */ 19 | public class AcFunDanmakuParser extends BaseDanmakuParser { 20 | 21 | @Override 22 | public Danmakus parse() { 23 | if (mDataSource != null && mDataSource instanceof JSONSource) { 24 | JSONSource jsonSource = (JSONSource) mDataSource; 25 | return doParse(jsonSource.data()); 26 | } 27 | return new Danmakus(); 28 | } 29 | 30 | /** 31 | * @param danmakuListData 弹幕数据 32 | * 传入的数组内包含普通弹幕,会员弹幕,锁定弹幕。 33 | * @return 转换后的Danmakus 34 | */ 35 | private Danmakus doParse(JSONArray danmakuListData) { 36 | Danmakus danmakus = new Danmakus(); 37 | if (danmakuListData == null || danmakuListData.length() == 0) { 38 | return danmakus; 39 | } 40 | for (int i = 0; i < danmakuListData.length(); i++) { 41 | try { 42 | JSONObject danmakuArray = danmakuListData.getJSONObject(i); 43 | if (danmakuArray != null) { 44 | danmakus = _parse(danmakuArray, danmakus); 45 | } 46 | } catch (JSONException e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | return danmakus; 51 | } 52 | 53 | private Danmakus _parse(JSONObject jsonObject, Danmakus danmakus) { 54 | if (danmakus == null) { 55 | danmakus = new Danmakus(); 56 | } 57 | if (jsonObject == null || jsonObject.length() == 0) { 58 | return danmakus; 59 | } 60 | for (int i = 0; i < jsonObject.length(); i++) { 61 | try { 62 | JSONObject obj = jsonObject; 63 | String c = obj.getString("c"); 64 | String[] values = c.split(","); 65 | if (values.length > 0) { 66 | int type = Integer.parseInt(values[2]); // 弹幕类型 67 | if (type == 7) 68 | continue; 69 | long time = (long) (Float.parseFloat(values[0]) * 1000); // 出现时间 70 | int color = Integer.parseInt(values[1]) | 0xFF000000; // 颜色 71 | float textSize = Float.parseFloat(values[3]); // 字体大小 72 | BaseDanmaku item = mContext.mDanmakuFactory.createDanmaku(type, mContext); 73 | if (item != null) { 74 | item.setTime(time); 75 | item.textSize = textSize * (mDispDensity - 0.6f); 76 | item.textColor = color; 77 | item.textShadowColor = color <= Color.BLACK ? Color.WHITE : Color.BLACK; 78 | DanmakuUtils.fillText(item, obj.optString("m", "....")); 79 | item.index = i; 80 | item.setTimer(mTimer); 81 | danmakus.addItem(item); 82 | } 83 | } 84 | } catch (JSONException e) { 85 | } catch (NumberFormatException e) { 86 | } 87 | } 88 | return danmakus; 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/danmaku/BaseDanmakuConverter.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.danmaku; 2 | 3 | import master.flame.danmaku.danmaku.model.BaseDanmaku; 4 | import master.flame.danmaku.danmaku.model.FBDanmaku; 5 | import master.flame.danmaku.danmaku.model.FTDanmaku; 6 | import master.flame.danmaku.danmaku.model.R2LDanmaku; 7 | 8 | import static master.flame.danmaku.danmaku.model.BaseDanmaku.TYPE_SCROLL_RL; 9 | 10 | /** 11 | * Created by long on 2016/12/22. 12 | * 弹幕转换器,用来进行自定义数据和弹幕的转换 13 | */ 14 | public abstract class BaseDanmakuConverter { 15 | 16 | // BaseDanmaku parseDanmaku(T info); 17 | 18 | public abstract T convertDanmaku(BaseDanmaku danmaku); 19 | 20 | /** 21 | * 对弹幕的基础数据进行初始化 22 | * @param data 23 | * @param danmaku 24 | */ 25 | protected void initData(T data, BaseDanmaku danmaku) { 26 | int danmakuType = TYPE_SCROLL_RL; 27 | if (danmaku instanceof R2LDanmaku) { 28 | danmakuType = BaseDanmaku.TYPE_SCROLL_RL; 29 | } else if (danmaku instanceof FBDanmaku) { 30 | danmakuType = BaseDanmaku.TYPE_FIX_BOTTOM; 31 | } else if (danmaku instanceof FTDanmaku) { 32 | danmakuType = BaseDanmaku.TYPE_FIX_TOP; 33 | } 34 | data.setType(danmakuType); 35 | data.setContent(danmaku.text.toString()); 36 | data.setTime(danmaku.getTime()); 37 | data.setTextSize(danmaku.textSize); 38 | data.setTextColor(danmaku.textColor); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/danmaku/BaseDanmakuData.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.danmaku; 2 | 3 | /** 4 | * Created by long on 2016/12/22. 5 | * 弹幕数据基类,用来限定弹幕类型 6 | */ 7 | public abstract class BaseDanmakuData { 8 | 9 | private 10 | @DanmakuType 11 | int type; 12 | private String content; 13 | private long time; 14 | private float textSize; 15 | private int textColor; 16 | 17 | public int getType() { 18 | return type; 19 | } 20 | 21 | public void setType(int type) { 22 | this.type = type; 23 | } 24 | 25 | public String getContent() { 26 | return content; 27 | } 28 | 29 | public void setContent(String content) { 30 | this.content = content; 31 | } 32 | 33 | public long getTime() { 34 | return time; 35 | } 36 | 37 | public void setTime(long time) { 38 | this.time = time; 39 | } 40 | 41 | public float getTextSize() { 42 | return textSize; 43 | } 44 | 45 | public void setTextSize(float textSize) { 46 | this.textSize = textSize; 47 | } 48 | 49 | public int getTextColor() { 50 | return textColor; 51 | } 52 | 53 | public void setTextColor(int textColor) { 54 | this.textColor = textColor; 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | return "BaseDanmakuData{" + 60 | "type=" + type + 61 | ", content='" + content + '\'' + 62 | ", time=" + time + 63 | ", textSize=" + textSize + 64 | ", textColor=" + textColor + 65 | '}'; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/danmaku/DanmakuType.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.danmaku; 2 | 3 | import android.support.annotation.IntDef; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | import static master.flame.danmaku.danmaku.model.BaseDanmaku.TYPE_FIX_BOTTOM; 11 | import static master.flame.danmaku.danmaku.model.BaseDanmaku.TYPE_FIX_TOP; 12 | import static master.flame.danmaku.danmaku.model.BaseDanmaku.TYPE_SCROLL_RL; 13 | 14 | /** 15 | * Created by long on 2016/12/22. 16 | * 限定3种弹幕类型: 17 | */ 18 | @Retention(RetentionPolicy.SOURCE) 19 | @Target({ElementType.FIELD, ElementType.PARAMETER}) 20 | @IntDef({TYPE_SCROLL_RL, TYPE_FIX_TOP, TYPE_FIX_BOTTOM}) 21 | public @interface DanmakuType { 22 | } 23 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/danmaku/OnDanmakuListener.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.danmaku; 2 | 3 | /** 4 | * Created by long on 2016/12/22. 5 | * 弹幕监听器 6 | */ 7 | public interface OnDanmakuListener { 8 | 9 | /** 10 | * 这个用来监听控制全屏模式下的发送弹幕操作,会在进入弹幕之前调用,并且根据返回值来判断是否可以进行发射弹幕操作,可用来处理用户登录情况 11 | * @return true:进入弹幕编辑;false:当前不能发射弹幕 12 | */ 13 | boolean isValid(); 14 | 15 | /** 16 | * 获取发射的弹幕数据 17 | * @param data 弹幕数据,默认为{@link master.flame.danmaku.danmaku.model.BaseDanmaku},如果设置自定义类型则为自定义格式 18 | */ 19 | void onDataObtain(T data); 20 | } 21 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/danmaku/VideoDanmakuSync.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.danmaku; 2 | 3 | import android.util.Log; 4 | 5 | import com.dl7.player.media.IjkPlayerView; 6 | 7 | import master.flame.danmaku.danmaku.model.AbsDanmakuSync; 8 | 9 | /** 10 | * Created by long on 2016/12/15. 11 | * 同步弹幕和video,貌似没法保持同步,可能我用的有问题- - 12 | */ 13 | @Deprecated 14 | public class VideoDanmakuSync extends AbsDanmakuSync { 15 | 16 | private final IjkPlayerView mPlayerView; 17 | 18 | public VideoDanmakuSync(IjkPlayerView playerView) { 19 | mPlayerView = playerView; 20 | } 21 | 22 | 23 | @Override 24 | public long getUptimeMillis() { 25 | if (mPlayerView != null) { 26 | Log.i("VideoDanmakuSync", ""+mPlayerView.getCurPosition()); 27 | return mPlayerView.getCurPosition(); 28 | } 29 | return -1L; 30 | } 31 | 32 | @Override 33 | public int getSyncState() { 34 | if (mPlayerView.isPlaying()) { 35 | Log.e("VideoDanmakuSync", "SYNC_STATE_PLAYING"); 36 | return SYNC_STATE_PLAYING; 37 | } else { 38 | Log.e("VideoDanmakuSync", "SYNC_STATE_HALT"); 39 | return SYNC_STATE_HALT; 40 | } 41 | } 42 | 43 | @Override 44 | public boolean isSyncPlayingState() { 45 | return true; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/media/AdapterMediaQuality.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.media; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.TextView; 8 | 9 | import com.dl7.player.R; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * Created by Rukey7 on 2016/10/29. 15 | */ 16 | 17 | public class AdapterMediaQuality extends BaseListAdapter { 18 | 19 | 20 | public AdapterMediaQuality(Context context, List datas) { 21 | super(context, datas); 22 | } 23 | 24 | public AdapterMediaQuality(Context context) { 25 | super(context); 26 | } 27 | 28 | @Override 29 | public View getView(final int i, View view, ViewGroup parent) { 30 | if (view == null) { 31 | view = LayoutInflater.from(mContext).inflate(R.layout.adapter_media_quality, parent, false); 32 | } 33 | TextView qualityDesc = (TextView) view.findViewById(R.id.tv_media_quality); 34 | qualityDesc.setText(mDatas.get(i).getDesc()); 35 | qualityDesc.setSelected(mDatas.get(i).isSelect()); 36 | return view; 37 | } 38 | 39 | private void _cleanSelected() { 40 | for (MediaQualityInfo info : mDatas) { 41 | if (info.isSelect()) { 42 | info.setSelect(false); 43 | } 44 | } 45 | } 46 | 47 | public void setMediaQuality(int quality) { 48 | for (MediaQualityInfo info : mDatas) { 49 | if (info.getIndex() == quality) { 50 | if (!info.isSelect()) { 51 | _cleanSelected(); 52 | info.setSelect(true); 53 | notifyDataSetChanged(); 54 | } 55 | return; 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/media/AndroidMediaController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Zhang Rui 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.dl7.player.media; 18 | 19 | import android.content.Context; 20 | import android.support.annotation.NonNull; 21 | import android.support.annotation.Nullable; 22 | import android.support.v7.app.ActionBar; 23 | import android.util.AttributeSet; 24 | import android.view.View; 25 | import android.widget.MediaController; 26 | 27 | import java.util.ArrayList; 28 | 29 | public class AndroidMediaController extends MediaController implements IMediaController { 30 | private ActionBar mActionBar; 31 | 32 | public AndroidMediaController(Context context, AttributeSet attrs) { 33 | super(context, attrs); 34 | initView(context); 35 | } 36 | 37 | public AndroidMediaController(Context context, boolean useFastForward) { 38 | super(context, useFastForward); 39 | initView(context); 40 | } 41 | 42 | public AndroidMediaController(Context context) { 43 | super(context); 44 | initView(context); 45 | } 46 | 47 | private void initView(Context context) { 48 | } 49 | 50 | public void setSupportActionBar(@Nullable ActionBar actionBar) { 51 | mActionBar = actionBar; 52 | if (isShowing()) { 53 | actionBar.show(); 54 | } else { 55 | actionBar.hide(); 56 | } 57 | } 58 | 59 | @Override 60 | public void show() { 61 | super.show(); 62 | if (mActionBar != null) 63 | mActionBar.show(); 64 | } 65 | 66 | @Override 67 | public void hide() { 68 | super.hide(); 69 | if (mActionBar != null) 70 | mActionBar.hide(); 71 | for (View view : mShowOnceArray) 72 | view.setVisibility(View.GONE); 73 | mShowOnceArray.clear(); 74 | } 75 | 76 | //---------- 77 | // Extends 78 | //---------- 79 | private ArrayList mShowOnceArray = new ArrayList(); 80 | 81 | public void showOnce(@NonNull View view) { 82 | mShowOnceArray.add(view); 83 | view.setVisibility(View.VISIBLE); 84 | show(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/media/BaseListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.media; 2 | 3 | import android.content.Context; 4 | import android.widget.BaseAdapter; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | /** 11 | * Created by long on 2016/6/7. 12 | * ListView的基础适配器 13 | */ 14 | public abstract class BaseListAdapter extends BaseAdapter { 15 | 16 | protected Context mContext; 17 | protected List mDatas; 18 | 19 | 20 | public BaseListAdapter(Context context) { 21 | this.mContext = context; 22 | this.mDatas = new ArrayList<>(); 23 | } 24 | 25 | public BaseListAdapter(Context context, List datas) { 26 | this.mContext = context; 27 | this.mDatas = datas; 28 | } 29 | 30 | public BaseListAdapter(Context context, T[] datas) { 31 | this.mContext = context; 32 | this.mDatas = new ArrayList(); 33 | Collections.addAll(mDatas, datas); 34 | } 35 | 36 | 37 | @Override 38 | public int getCount() { 39 | return mDatas.size(); 40 | } 41 | 42 | @Override 43 | public T getItem(int position) { 44 | return mDatas.get(position); 45 | } 46 | 47 | @Override 48 | public long getItemId(int position) { 49 | return position; 50 | } 51 | 52 | 53 | 54 | /** 55 | * 更新数据,替换原有数据 56 | * @param items 57 | */ 58 | public void updateItems(List items) { 59 | mDatas = items; 60 | notifyDataSetChanged(); 61 | } 62 | 63 | /** 64 | * 插入一条数据 65 | * @param item 数据 66 | */ 67 | public void addItem(T item) { 68 | mDatas.add(0, item); 69 | notifyDataSetChanged(); 70 | } 71 | 72 | /** 73 | * 插入一条数据 74 | * @param item 数据 75 | * @param position 插入位置 76 | */ 77 | public void addItem(T item, int position) { 78 | position = Math.min(position, mDatas.size()); 79 | mDatas.add(position, item); 80 | notifyDataSetChanged(); 81 | } 82 | 83 | /** 84 | * 在列表尾添加一串数据 85 | * @param items 86 | */ 87 | public void addItems(List items) { 88 | mDatas.addAll(items); 89 | } 90 | 91 | /** 92 | * 移除一条数据 93 | * @param position 位置 94 | */ 95 | public void removeItem(int position) { 96 | if (position > mDatas.size() - 1) { 97 | return; 98 | } 99 | mDatas.remove(position); 100 | notifyDataSetChanged(); 101 | } 102 | 103 | /** 104 | * 移除一条数据 105 | * @param item 数据 106 | */ 107 | public void removeItem(T item) { 108 | int pos = 0; 109 | for (T info : mDatas) { 110 | if (item.hashCode() == info.hashCode()) { 111 | removeItem(pos); 112 | break; 113 | } 114 | pos++; 115 | } 116 | } 117 | 118 | /** 119 | * 清除所有数据 120 | */ 121 | public void cleanItems() { 122 | mDatas.clear(); 123 | notifyDataSetChanged(); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/media/FileMediaDataSource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Zhang Rui 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.dl7.player.media; 18 | 19 | import java.io.File; 20 | import java.io.IOException; 21 | import java.io.RandomAccessFile; 22 | 23 | import tv.danmaku.ijk.media.player.misc.IMediaDataSource; 24 | 25 | public class FileMediaDataSource implements IMediaDataSource { 26 | private RandomAccessFile mFile; 27 | private long mFileSize; 28 | 29 | public FileMediaDataSource(File file) throws IOException { 30 | mFile = new RandomAccessFile(file, "r"); 31 | mFileSize = mFile.length(); 32 | } 33 | 34 | @Override 35 | public int readAt(long position, byte[] buffer, int offset, int size) throws IOException { 36 | if (mFile.getFilePointer() != position) 37 | mFile.seek(position); 38 | 39 | if (size == 0) 40 | return 0; 41 | 42 | return mFile.read(buffer, 0, size); 43 | } 44 | 45 | @Override 46 | public long getSize() throws IOException { 47 | return mFileSize; 48 | } 49 | 50 | @Override 51 | public void close() throws IOException { 52 | mFileSize = 0; 53 | mFile.close(); 54 | mFile = null; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/media/IMediaController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Zhang Rui 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.dl7.player.media; 18 | 19 | import android.view.View; 20 | import android.widget.MediaController; 21 | 22 | public interface IMediaController { 23 | void hide(); 24 | 25 | boolean isShowing(); 26 | 27 | void setAnchorView(View view); 28 | 29 | void setEnabled(boolean enabled); 30 | 31 | void setMediaPlayer(MediaController.MediaPlayerControl player); 32 | 33 | void show(int timeout); 34 | 35 | void show(); 36 | 37 | //---------- 38 | // Extends 39 | //---------- 40 | void showOnce(View view); 41 | } 42 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/media/IRenderView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Zhang Rui 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.dl7.player.media; 18 | 19 | import android.graphics.Bitmap; 20 | import android.graphics.Matrix; 21 | import android.graphics.SurfaceTexture; 22 | import android.support.annotation.NonNull; 23 | import android.support.annotation.Nullable; 24 | import android.view.Surface; 25 | import android.view.SurfaceHolder; 26 | import android.view.View; 27 | 28 | import tv.danmaku.ijk.media.player.IMediaPlayer; 29 | 30 | public interface IRenderView { 31 | /** 32 | * 视频显示模式:View 是视频画面能显示的控件 33 | * 0 -> 填满View一边,另一边按比例缩小,整个视频显示在View里面 34 | * 1 -> 整个填满View,可能有一边会被裁剪一部分画面 35 | * 2 -> 根据原始视频大小来测量,不会超出View范围 36 | * 3 -> 按View的原始测量值来设定 37 | * 4 -> 按16:9的比例来处理,不会超出View范围 38 | * 5 -> 按4:3的比例来处理,不会超出View范围 39 | */ 40 | int AR_ASPECT_FIT_PARENT = 0; // without clip 41 | int AR_ASPECT_FILL_PARENT = 1; // may clip 42 | int AR_ASPECT_WRAP_CONTENT = 2; 43 | int AR_MATCH_PARENT = 3; 44 | int AR_16_9_FIT_PARENT = 4; 45 | int AR_4_3_FIT_PARENT = 5; 46 | 47 | View getView(); 48 | 49 | boolean shouldWaitForResize(); 50 | 51 | void setVideoSize(int videoWidth, int videoHeight); 52 | 53 | void setVideoSampleAspectRatio(int videoSarNum, int videoSarDen); 54 | 55 | void setVideoRotation(int degree); 56 | 57 | void setAspectRatio(int aspectRatio); 58 | 59 | void addRenderCallback(@NonNull IRenderCallback callback); 60 | 61 | void removeRenderCallback(@NonNull IRenderCallback callback); 62 | 63 | // add, 设置 Matrix,来做缩放操作 64 | void setTransform(Matrix transform); 65 | // add, 获取 Matrix,来做缩放操作 66 | Matrix getTransform(); 67 | // add, 获取截图 68 | Bitmap getVideoScreenshot(); 69 | 70 | interface ISurfaceHolder { 71 | void bindToMediaPlayer(IMediaPlayer mp); 72 | 73 | @NonNull 74 | IRenderView getRenderView(); 75 | 76 | @Nullable 77 | SurfaceHolder getSurfaceHolder(); 78 | 79 | @Nullable 80 | Surface openSurface(); 81 | 82 | @Nullable 83 | SurfaceTexture getSurfaceTexture(); 84 | } 85 | 86 | interface IRenderCallback { 87 | /** 88 | * @param holder 89 | * @param width could be 0 90 | * @param height could be 0 91 | */ 92 | void onSurfaceCreated(@NonNull ISurfaceHolder holder, int width, int height); 93 | 94 | /** 95 | * @param holder 96 | * @param format could be 0 97 | * @param width 98 | * @param height 99 | */ 100 | void onSurfaceChanged(@NonNull ISurfaceHolder holder, int format, int width, int height); 101 | 102 | void onSurfaceDestroyed(@NonNull ISurfaceHolder holder); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/media/MediaPlayerCompat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Zhang Rui 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.dl7.player.media; 18 | 19 | import tv.danmaku.ijk.media.player.IMediaPlayer; 20 | import tv.danmaku.ijk.media.player.IjkMediaPlayer; 21 | import tv.danmaku.ijk.media.player.MediaPlayerProxy; 22 | import tv.danmaku.ijk.media.player.TextureMediaPlayer; 23 | 24 | public class MediaPlayerCompat { 25 | 26 | public static String getName(IMediaPlayer mp) { 27 | if (mp == null) { 28 | return "null"; 29 | } else if (mp instanceof TextureMediaPlayer) { 30 | StringBuilder sb = new StringBuilder("TextureMediaPlayer <"); 31 | IMediaPlayer internalMediaPlayer = ((TextureMediaPlayer) mp).getInternalMediaPlayer(); 32 | if (internalMediaPlayer == null) { 33 | sb.append("null>"); 34 | } else { 35 | sb.append(internalMediaPlayer.getClass().getSimpleName()); 36 | sb.append(">"); 37 | } 38 | return sb.toString(); 39 | } else { 40 | return mp.getClass().getSimpleName(); 41 | } 42 | } 43 | 44 | public static IjkMediaPlayer getIjkMediaPlayer(IMediaPlayer mp) { 45 | IjkMediaPlayer ijkMediaPlayer = null; 46 | if (mp == null) { 47 | return null; 48 | } 49 | if (mp instanceof IjkMediaPlayer) { 50 | ijkMediaPlayer = (IjkMediaPlayer) mp; 51 | } else if (mp instanceof MediaPlayerProxy && ((MediaPlayerProxy) mp).getInternalMediaPlayer() instanceof IjkMediaPlayer) { 52 | ijkMediaPlayer = (IjkMediaPlayer) ((MediaPlayerProxy) mp).getInternalMediaPlayer(); 53 | } 54 | return ijkMediaPlayer; 55 | } 56 | 57 | public static void selectTrack(IMediaPlayer mp, int stream) { 58 | IjkMediaPlayer ijkMediaPlayer = getIjkMediaPlayer(mp); 59 | if (ijkMediaPlayer == null) 60 | return; 61 | ijkMediaPlayer.selectTrack(stream); 62 | } 63 | 64 | public static void deselectTrack(IMediaPlayer mp, int stream) { 65 | IjkMediaPlayer ijkMediaPlayer = getIjkMediaPlayer(mp); 66 | if (ijkMediaPlayer == null) 67 | return; 68 | ijkMediaPlayer.deselectTrack(stream); 69 | } 70 | 71 | public static int getSelectedTrack(IMediaPlayer mp, int trackType) { 72 | IjkMediaPlayer ijkMediaPlayer = getIjkMediaPlayer(mp); 73 | if (ijkMediaPlayer == null) 74 | return -1; 75 | return ijkMediaPlayer.getSelectedTrack(trackType); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/media/MediaPlayerParams.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.media; 2 | 3 | public class MediaPlayerParams { 4 | 5 | /**================================= 播放状态 =================================*/ 6 | // 空闲 7 | public static final int STATE_IDLE = 330; 8 | // 错误 9 | public static final int STATE_ERROR = 331; 10 | // 加载中 11 | public static final int STATE_PREPARING = 332; 12 | // 加载完成 13 | public static final int STATE_PREPARED = 333; 14 | // 播放中 15 | public static final int STATE_PLAYING = 334; 16 | // 暂停 17 | public static final int STATE_PAUSED = 335; 18 | // 结束 19 | public static final int STATE_COMPLETED = 336; 20 | 21 | /** 22 | * ============================ 弹幕状态 ============================ 23 | */ 24 | } 25 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/media/MediaQualityInfo.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.media; 2 | 3 | import com.dl7.player.media.IjkPlayerView.MediaQuality; 4 | 5 | /** 6 | * Created by Rukey7 on 2016/10/29. 7 | */ 8 | 9 | public final class MediaQualityInfo { 10 | 11 | private int index; 12 | private String desc; 13 | private boolean isSelect; 14 | 15 | public MediaQualityInfo(@MediaQuality int index, String desc, boolean isSelect) { 16 | this.index = index; 17 | this.desc = desc; 18 | this.isSelect = isSelect; 19 | } 20 | 21 | public @MediaQuality int getIndex() { 22 | return index; 23 | } 24 | 25 | public void setIndex(int index) { 26 | this.index = index; 27 | } 28 | 29 | public String getDesc() { 30 | return desc; 31 | } 32 | 33 | public void setDesc(String desc) { 34 | this.desc = desc; 35 | } 36 | 37 | public boolean isSelect() { 38 | return isSelect; 39 | } 40 | 41 | public void setSelect(boolean select) { 42 | isSelect = select; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return "MediaQualityInfo{" + 48 | "index=" + index + 49 | ", desc='" + desc + '\'' + 50 | ", isSelect=" + isSelect + 51 | '}'; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/utils/AnimHelper.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.utils; 2 | 3 | import android.animation.AnimatorSet; 4 | import android.animation.ObjectAnimator; 5 | import android.animation.ValueAnimator; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.view.animation.AccelerateInterpolator; 9 | 10 | /** 11 | * Created by long on 2016/11/4. 12 | */ 13 | 14 | public final class AnimHelper { 15 | 16 | private AnimHelper() { 17 | throw new AssertionError(); 18 | } 19 | 20 | 21 | /** 22 | * 执行从右滑入动画 23 | * @param view 24 | * @param startX 25 | * @param endX 26 | * @param duration 27 | */ 28 | public static void doSlideRightIn(View view, int startX, int endX, int duration) { 29 | ObjectAnimator translationX = ObjectAnimator.ofFloat(view, "translationX", startX, endX); 30 | ObjectAnimator alpha = ObjectAnimator.ofFloat(view, "alpha", 0, 1); 31 | AnimatorSet set = new AnimatorSet(); 32 | set.setDuration(duration); 33 | set.playTogether(translationX, alpha); 34 | set.start(); 35 | } 36 | 37 | /** 38 | * 裁剪视图宽度 39 | * @param view 40 | * @param srcWidth 41 | * @param endWidth 42 | * @param duration 43 | */ 44 | public static void doClipViewWidth(final View view, int srcWidth, int endWidth, int duration) { 45 | ValueAnimator valueAnimator = ValueAnimator.ofInt(srcWidth, endWidth).setDuration(duration); 46 | valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 47 | @Override 48 | public void onAnimationUpdate(ValueAnimator valueAnimator) { 49 | int width = (int) valueAnimator.getAnimatedValue(); 50 | ViewGroup.LayoutParams layoutParams = view.getLayoutParams(); 51 | layoutParams.width = width; 52 | view.setLayoutParams(layoutParams); 53 | } 54 | }); 55 | valueAnimator.setInterpolator(new AccelerateInterpolator()); 56 | valueAnimator.start(); 57 | } 58 | 59 | /** 60 | * 裁剪视图宽度 61 | * @param view 62 | * @param srcHeight 63 | * @param endHeight 64 | * @param duration 65 | */ 66 | public static void doClipViewHeight(final View view, int srcHeight, int endHeight, int duration) { 67 | ValueAnimator valueAnimator = ValueAnimator.ofInt(srcHeight, endHeight).setDuration(duration); 68 | valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 69 | @Override 70 | public void onAnimationUpdate(ValueAnimator valueAnimator) { 71 | int width = (int) valueAnimator.getAnimatedValue(); 72 | ViewGroup.LayoutParams layoutParams = view.getLayoutParams(); 73 | layoutParams.height = width; 74 | view.setLayoutParams(layoutParams); 75 | } 76 | }); 77 | valueAnimator.setInterpolator(new AccelerateInterpolator()); 78 | valueAnimator.start(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/utils/MotionEventUtils.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.utils; 2 | 3 | import android.graphics.PointF; 4 | import android.view.MotionEvent; 5 | 6 | /** 7 | * Created by Rukey7 on 2016/11/21. 8 | */ 9 | 10 | public final class MotionEventUtils { 11 | 12 | public static final int FINGER_FLAG_1 = 601; 13 | public static final int FINGER_FLAG_2 = 602; 14 | public static final int FINGER_FLAG_3 = 603; 15 | 16 | private MotionEventUtils() { 17 | throw new AssertionError(); 18 | } 19 | 20 | 21 | /** 22 | * Determine the space between the first two fingers 23 | */ 24 | public static float calcSpacing(MotionEvent event, int index1, int index2) { 25 | float x = event.getX(index1) - event.getX(index2); 26 | float y = event.getY(index1) - event.getY(index2); 27 | return (float) Math.sqrt(x * x + y * y); 28 | } 29 | 30 | /** 31 | * Determine the space between the two fingers 32 | * @param event 33 | * @param fingerFlag 34 | * @return 35 | */ 36 | public static float calcSpacing(MotionEvent event, int fingerFlag) { 37 | float x, y; 38 | if (FINGER_FLAG_1 == fingerFlag) { 39 | x = (event.getX(0) + event.getX(1)) / 2 - event.getX(2); 40 | y = (event.getY(0) + event.getY(1)) / 2 - event.getY(2); 41 | } else if (FINGER_FLAG_2 == fingerFlag) { 42 | x = (event.getX(0) + event.getX(2)) / 2 - event.getX(1); 43 | y = (event.getY(0) + event.getY(2)) / 2 - event.getY(1); 44 | } else if (FINGER_FLAG_3 == fingerFlag) { 45 | x = (event.getX(2) + event.getX(1)) / 2 - event.getX(0); 46 | y = (event.getY(2) + event.getY(1)) / 2 - event.getY(0); 47 | } else { 48 | x = (event.getX(0) - event.getX(1)); 49 | y = (event.getY(0) - event.getY(1)); 50 | } 51 | return (float) Math.sqrt(x * x + y * y); 52 | } 53 | 54 | /** 55 | * Calculate the mid point of two pointers 56 | */ 57 | public static void midPoint(PointF point, MotionEvent event) { 58 | float x = event.getX(0) + event.getX(1) + event.getX(2); 59 | float y = event.getY(0) + event.getY(1) + event.getY(2); 60 | point.set(x / 3, y / 3); 61 | } 62 | 63 | /** 64 | * 计算靠的最近的两指 65 | * @param event 66 | * @return 67 | */ 68 | public static int calcFingerFlag(MotionEvent event) { 69 | float space1 = calcSpacing(event, 0, 1); 70 | float space2 = calcSpacing(event, 0, 2); 71 | float space3 = calcSpacing(event, 2, 1); 72 | float minSpace = Math.min(space1, Math.min(space2, space3)); 73 | if (minSpace == space1) { 74 | return FINGER_FLAG_1; 75 | } else if (minSpace == space2) { 76 | return FINGER_FLAG_2; 77 | } else if (minSpace == space3) { 78 | return FINGER_FLAG_3; 79 | } else { 80 | return -1; 81 | } 82 | } 83 | 84 | /** 85 | * Calculate the degree to be rotated by. 86 | * 87 | * @param event 88 | * @return Degrees 89 | */ 90 | public static float rotation(MotionEvent event, int fingerFlag) { 91 | double delta_x, delta_y; 92 | if (FINGER_FLAG_1 == fingerFlag) { 93 | delta_x = (event.getX(0) + event.getX(1)) / 2 - event.getX(2); 94 | delta_y = (event.getY(0) + event.getY(1)) / 2 - event.getY(2); 95 | } else if (FINGER_FLAG_2 == fingerFlag) { 96 | delta_x = (event.getX(0) + event.getX(2)) / 2 - event.getX(1); 97 | delta_y = (event.getY(0) + event.getY(2)) / 2 - event.getY(1); 98 | } else if (FINGER_FLAG_3 == fingerFlag) { 99 | delta_x = (event.getX(2) + event.getX(1)) / 2 - event.getX(0); 100 | delta_y = (event.getY(2) + event.getY(1)) / 2 - event.getY(0); 101 | } else { 102 | delta_x = (event.getX(0) - event.getX(1)); 103 | delta_y = (event.getY(0) - event.getY(1)); 104 | } 105 | double radians = Math.atan2(delta_y, delta_x); 106 | return (float) Math.toDegrees(radians); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/utils/NavUtils.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.utils; 2 | 3 | import android.content.Context; 4 | import android.content.res.Resources; 5 | 6 | import java.lang.reflect.Method; 7 | 8 | /** 9 | * Created by long on 2016/10/10. 10 | * 导航栏工具类 11 | */ 12 | public final class NavUtils { 13 | 14 | private NavUtils() { 15 | throw new RuntimeException("NavUtils cannot be initialized!"); 16 | } 17 | 18 | /** 19 | * 获取底部导航栏高度 20 | * @param activity 21 | * @return 22 | */ 23 | public static int getNavigationBarHeight(Context activity) { 24 | if (!checkDeviceHasNavigationBar(activity)) { 25 | return 0; 26 | } 27 | Resources resources = activity.getResources(); 28 | int resourceId = resources.getIdentifier("navigation_bar_height", 29 | "dimen", "android"); 30 | //获取NavigationBar的高度 31 | int height = resources.getDimensionPixelSize(resourceId); 32 | return height; 33 | } 34 | 35 | /** 36 | * 检测是否有虚拟键 37 | * @param context 38 | * @return 39 | */ 40 | public static boolean checkDeviceHasNavigationBar(Context context) { 41 | boolean hasNavigationBar = false; 42 | Resources rs = context.getResources(); 43 | int id = rs.getIdentifier("config_showNavigationBar", "bool", "android"); 44 | if (id > 0) { 45 | hasNavigationBar = rs.getBoolean(id); 46 | } 47 | try { 48 | Class systemPropertiesClass = Class.forName("android.os.SystemProperties"); 49 | Method m = systemPropertiesClass.getMethod("get", String.class); 50 | String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys"); 51 | if ("1".equals(navBarOverride)) { 52 | hasNavigationBar = false; 53 | } else if ("0".equals(navBarOverride)) { 54 | hasNavigationBar = true; 55 | } 56 | } catch (Exception e) { 57 | 58 | } 59 | return hasNavigationBar; 60 | 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/utils/NetWorkUtils.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.utils; 2 | 3 | import android.content.Context; 4 | import android.net.ConnectivityManager; 5 | import android.net.NetworkInfo; 6 | import android.telephony.TelephonyManager; 7 | import android.text.TextUtils; 8 | 9 | /** 10 | * NetWork Utils 11 | *
    12 | * Attentions 13 | *
  • You should add android.permission.ACCESS_NETWORK_STATE in manifest, to get network status.
  • 14 | *
15 | * 16 | * @author Trinea 2014-11-03 17 | */ 18 | public class NetWorkUtils { 19 | 20 | public static final String NETWORK_TYPE_WIFI = "wifi"; 21 | public static final String NETWORK_TYPE_3G = "eg"; 22 | public static final String NETWORK_TYPE_2G = "2g"; 23 | public static final String NETWORK_TYPE_WAP = "wap"; 24 | public static final String NETWORK_TYPE_UNKNOWN = "unknown"; 25 | public static final String NETWORK_TYPE_DISCONNECT = "disconnect"; 26 | 27 | /** 28 | * Get network type 29 | * 30 | * @param context 31 | * @return 32 | */ 33 | public static int getNetworkType(Context context) { 34 | ConnectivityManager connectivityManager = (ConnectivityManager)context 35 | .getSystemService(Context.CONNECTIVITY_SERVICE); 36 | NetworkInfo networkInfo = connectivityManager == null ? null : connectivityManager.getActiveNetworkInfo(); 37 | return networkInfo == null ? -1 : networkInfo.getType(); 38 | } 39 | 40 | /** 41 | * Get network type name 42 | * 43 | * @param context 44 | * @return 45 | */ 46 | public static String getNetworkTypeName(Context context) { 47 | ConnectivityManager manager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); 48 | NetworkInfo networkInfo; 49 | String type = NETWORK_TYPE_DISCONNECT; 50 | if (manager == null || (networkInfo = manager.getActiveNetworkInfo()) == null) { 51 | return type; 52 | } 53 | 54 | if (networkInfo.isConnected()) { 55 | String typeName = networkInfo.getTypeName(); 56 | if ("WIFI".equalsIgnoreCase(typeName)) { 57 | type = NETWORK_TYPE_WIFI; 58 | } else if ("MOBILE".equalsIgnoreCase(typeName)) { 59 | String proxyHost = android.net.Proxy.getDefaultHost(); 60 | type = TextUtils.isEmpty(proxyHost) ? (isFastMobileNetwork(context) ? NETWORK_TYPE_3G : NETWORK_TYPE_2G) 61 | : NETWORK_TYPE_WAP; 62 | } else { 63 | type = NETWORK_TYPE_UNKNOWN; 64 | } 65 | } 66 | return type; 67 | } 68 | 69 | /** 70 | * Whether is fast mobile network 71 | * 72 | * @param context 73 | * @return 74 | */ 75 | private static boolean isFastMobileNetwork(Context context) { 76 | TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); 77 | if (telephonyManager == null) { 78 | return false; 79 | } 80 | 81 | switch (telephonyManager.getNetworkType()) { 82 | case TelephonyManager.NETWORK_TYPE_1xRTT: 83 | return false; 84 | case TelephonyManager.NETWORK_TYPE_CDMA: 85 | return false; 86 | case TelephonyManager.NETWORK_TYPE_EDGE: 87 | return false; 88 | case TelephonyManager.NETWORK_TYPE_EVDO_0: 89 | return true; 90 | case TelephonyManager.NETWORK_TYPE_EVDO_A: 91 | return true; 92 | case TelephonyManager.NETWORK_TYPE_GPRS: 93 | return false; 94 | case TelephonyManager.NETWORK_TYPE_HSDPA: 95 | return true; 96 | case TelephonyManager.NETWORK_TYPE_HSPA: 97 | return true; 98 | case TelephonyManager.NETWORK_TYPE_HSUPA: 99 | return true; 100 | case TelephonyManager.NETWORK_TYPE_UMTS: 101 | return true; 102 | case TelephonyManager.NETWORK_TYPE_EHRPD: 103 | return true; 104 | case TelephonyManager.NETWORK_TYPE_EVDO_B: 105 | return true; 106 | case TelephonyManager.NETWORK_TYPE_HSPAP: 107 | return true; 108 | case TelephonyManager.NETWORK_TYPE_IDEN: 109 | return false; 110 | case TelephonyManager.NETWORK_TYPE_LTE: 111 | return true; 112 | case TelephonyManager.NETWORK_TYPE_UNKNOWN: 113 | return false; 114 | default: 115 | return false; 116 | } 117 | } 118 | 119 | /** 120 | * 网络是否可用 121 | * @param context 122 | * @return 123 | */ 124 | public static boolean isNetworkAvailable(Context context) { 125 | try { 126 | ConnectivityManager cm = 127 | (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 128 | NetworkInfo info = cm.getActiveNetworkInfo(); 129 | return null != info && info.isConnected(); 130 | } catch (Exception e) { 131 | e.printStackTrace(); 132 | } 133 | return false; 134 | } 135 | 136 | /** 137 | * 判断MOBILE网络是否可用 138 | */ 139 | public static boolean isMobileConnected(Context context) { 140 | if (context != null) { 141 | ConnectivityManager mConnectivityManager = (ConnectivityManager) context 142 | .getSystemService(Context.CONNECTIVITY_SERVICE); 143 | NetworkInfo mMobileNetworkInfo = mConnectivityManager 144 | .getNetworkInfo(ConnectivityManager.TYPE_MOBILE); 145 | if (mMobileNetworkInfo != null && mMobileNetworkInfo.isAvailable()) { 146 | return mMobileNetworkInfo.isConnected(); 147 | } 148 | } 149 | return false; 150 | } 151 | 152 | /** 153 | * 判断WIFI网络是否可用 154 | */ 155 | public static boolean isWifiConnected(Context context) { 156 | if (context != null) { 157 | ConnectivityManager mConnectivityManager = (ConnectivityManager) context 158 | .getSystemService(Context.CONNECTIVITY_SERVICE); 159 | NetworkInfo mWiFiNetworkInfo = mConnectivityManager 160 | .getNetworkInfo(ConnectivityManager.TYPE_WIFI); 161 | if (mWiFiNetworkInfo != null && mWiFiNetworkInfo.isAvailable()) { 162 | return mWiFiNetworkInfo.isConnected(); 163 | } 164 | } 165 | return false; 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/utils/SDCardUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 Peng fei Pan 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 com.dl7.player.utils; 18 | 19 | import android.os.Build; 20 | import android.os.Environment; 21 | import android.os.StatFs; 22 | 23 | import java.io.File; 24 | 25 | /** 26 | * SD卡工具箱 27 | */ 28 | public class SDCardUtils { 29 | /** 30 | * 获取SD卡的状态 31 | */ 32 | public static String getState() { 33 | return Environment.getExternalStorageState(); 34 | } 35 | 36 | 37 | /** 38 | * SD卡是否可用 39 | * 40 | * @return 只有当SD卡已经安装并且准备好了才返回true 41 | */ 42 | public static boolean isAvailable() { 43 | return getState().equals(Environment.MEDIA_MOUNTED); 44 | } 45 | 46 | 47 | /** 48 | * 获取SD卡的根目录 49 | * 50 | * @return null:不存在SD卡 51 | */ 52 | public static File getRootDirectory() { 53 | return isAvailable() ? Environment.getExternalStorageDirectory() : null; 54 | } 55 | 56 | 57 | /** 58 | * 获取SD卡的根路径 59 | * 60 | * @return null:不存在SD卡 61 | */ 62 | public static String getRootPath() { 63 | File rootDirectory = getRootDirectory(); 64 | return rootDirectory != null ? rootDirectory.getPath() : null; 65 | } 66 | 67 | /** 68 | * 获取sd卡路径 69 | * 70 | * @return Stringpath 71 | */ 72 | public static String getSDPath() { 73 | File sdDir = null; 74 | boolean sdCardExist = Environment.getExternalStorageState() 75 | .equals(Environment.MEDIA_MOUNTED); //判断sd卡是否存在 76 | if (sdCardExist) { 77 | sdDir = Environment.getExternalStorageDirectory();//获取跟目录 78 | } 79 | return sdDir.toString(); 80 | } 81 | 82 | /** 83 | * 获取空闲的空间大小 84 | * @param path 文件路径 85 | * @return 空间大小 86 | */ 87 | public static long getFreeSpaceBytes(final String path) { 88 | long freeSpaceBytes; 89 | final StatFs statFs = new StatFs(path); 90 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { 91 | freeSpaceBytes = statFs.getAvailableBytes(); 92 | } else { 93 | //noinspection deprecation 94 | freeSpaceBytes = statFs.getAvailableBlocks() * (long) statFs.getBlockSize(); 95 | } 96 | 97 | return freeSpaceBytes; 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/utils/SoftInputUtils.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.utils; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.view.View; 6 | import android.view.inputmethod.InputMethodManager; 7 | 8 | /** 9 | * SoftInputUtils 10 | * 11 | * @author Trinea 2014-5-07 12 | */ 13 | public class SoftInputUtils { 14 | 15 | private SoftInputUtils() { 16 | throw new AssertionError(); 17 | } 18 | 19 | 20 | /** 21 | * 关闭键盘事件. 22 | * 23 | * @param context the context 24 | */ 25 | public static void closeSoftInput(Context context) { 26 | InputMethodManager inputMethodManager = (InputMethodManager) context 27 | .getSystemService(Context.INPUT_METHOD_SERVICE); 28 | if (inputMethodManager != null 29 | && ((Activity) context).getCurrentFocus() != null) { 30 | inputMethodManager.hideSoftInputFromWindow(((Activity) context) 31 | .getCurrentFocus().getWindowToken(), 32 | InputMethodManager.HIDE_NOT_ALWAYS); 33 | } 34 | } 35 | 36 | /** 37 | * 弹出输入法 38 | * 39 | * @param context context 40 | * @param view 编辑控件 41 | */ 42 | public static void setEditFocusable(final Context context, final View view) { 43 | view.setFocusableInTouchMode(true); 44 | view.requestFocus(); 45 | InputMethodManager inputMethodManager = (InputMethodManager) context 46 | .getSystemService(Context.INPUT_METHOD_SERVICE); 47 | inputMethodManager.showSoftInput(view, 0); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/utils/StringUtils.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.utils; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.Date; 5 | 6 | /** 7 | * Created by long on 2016/10/18. 8 | */ 9 | 10 | public final class StringUtils { 11 | 12 | private StringUtils() { 13 | throw new AssertionError(); 14 | } 15 | 16 | 17 | /** 18 | * 时长格式化显示 19 | */ 20 | public static String generateTime(long time) { 21 | int totalSeconds = (int) (time / 1000); 22 | int seconds = totalSeconds % 60; 23 | int minutes = totalSeconds / 60; 24 | // int minutes = (totalSeconds / 60) % 60; 25 | // int hours = totalSeconds / 3600; 26 | return minutes > 99 ? String.format("%d:%02d", minutes, seconds) : String.format("%02d:%02d", minutes, seconds); 27 | } 28 | 29 | /** 30 | * 下载速度格式化显示 31 | */ 32 | public static String getFormatSize(int size) { 33 | long fileSize = (long) size; 34 | String showSize = ""; 35 | if (fileSize >= 0 && fileSize < 1024) { 36 | showSize = fileSize + "Kb/s"; 37 | } else if (fileSize >= 1024 && fileSize < (1024 * 1024)) { 38 | showSize = Long.toString(fileSize / 1024) + "KB/s"; 39 | } else if (fileSize >= (1024 * 1024) && fileSize < (1024 * 1024 * 1024)) { 40 | showSize = Long.toString(fileSize / (1024 * 1024)) + "MB/s"; 41 | } 42 | return showSize; 43 | } 44 | 45 | /** 46 | * 获取格式化当前时间 47 | * @return 48 | */ 49 | public static String getCurFormatTime() { 50 | SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); 51 | return sdf.format(new Date(System.currentTimeMillis())); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/utils/WindowUtils.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.utils; /** 2 | * Copyright 2014 Zhenguo Jin (jinzhenguo1990@gmail.com) 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 | import android.animation.ValueAnimator; 18 | import android.app.Activity; 19 | import android.content.Context; 20 | import android.content.pm.ActivityInfo; 21 | import android.content.res.Configuration; 22 | import android.util.DisplayMetrics; 23 | import android.view.Surface; 24 | import android.view.Window; 25 | import android.view.WindowManager; 26 | 27 | /** 28 | * 窗口工具箱 29 | * 30 | * @author zhenguo 31 | */ 32 | public final class WindowUtils { 33 | 34 | /** 35 | * Don't let anyone instantiate this class. 36 | */ 37 | private WindowUtils() { 38 | throw new Error("Do not need instantiate!"); 39 | } 40 | 41 | /** 42 | * 获取当前窗口的旋转角度 43 | * 44 | * @param activity activity 45 | * @return int 46 | */ 47 | public static int getDisplayRotation(Activity activity) { 48 | switch (activity.getWindowManager().getDefaultDisplay().getRotation()) { 49 | case Surface.ROTATION_0: 50 | return 0; 51 | case Surface.ROTATION_90: 52 | return 90; 53 | case Surface.ROTATION_180: 54 | return 180; 55 | case Surface.ROTATION_270: 56 | return 270; 57 | default: 58 | return 0; 59 | } 60 | } 61 | 62 | /** 63 | * 当前是否是横屏 64 | * 65 | * @param context context 66 | * @return boolean 67 | */ 68 | public static final boolean isLandscape(Context context) { 69 | return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; 70 | } 71 | 72 | /** 73 | * 当前是否是竖屏 74 | * 75 | * @param context context 76 | * @return boolean 77 | */ 78 | public static final boolean isPortrait(Context context) { 79 | return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT; 80 | } 81 | 82 | /** 83 | * 调整窗口的透明度 1.0f,0.5f 变暗 84 | * 85 | * @param from from>=0&&from<=1.0f 86 | * @param to to>=0&&to<=1.0f 87 | * @param context 当前的activity 88 | */ 89 | public static void dimBackground(final float from, final float to, Activity context) { 90 | final Window window = context.getWindow(); 91 | ValueAnimator valueAnimator = ValueAnimator.ofFloat(from, to); 92 | valueAnimator.setDuration(500); 93 | valueAnimator.addUpdateListener( 94 | new ValueAnimator.AnimatorUpdateListener() { 95 | @Override 96 | public void onAnimationUpdate(ValueAnimator animation) { 97 | WindowManager.LayoutParams params 98 | = window.getAttributes(); 99 | params.alpha = (Float) animation.getAnimatedValue(); 100 | window.setAttributes(params); 101 | } 102 | }); 103 | valueAnimator.start(); 104 | } 105 | 106 | /** 107 | * 获取界面方向 108 | */ 109 | public static int getScreenOrientation(Activity activity) { 110 | int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); 111 | DisplayMetrics dm = new DisplayMetrics(); 112 | activity.getWindowManager().getDefaultDisplay().getMetrics(dm); 113 | int width = dm.widthPixels; 114 | int height = dm.heightPixels; 115 | int orientation; 116 | // if the device's natural orientation is portrait: 117 | if ((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) && height > width || 118 | (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) && width > height) { 119 | switch (rotation) { 120 | case Surface.ROTATION_0: 121 | orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; 122 | break; 123 | case Surface.ROTATION_90: 124 | orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; 125 | break; 126 | case Surface.ROTATION_180: 127 | orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; 128 | break; 129 | case Surface.ROTATION_270: 130 | orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; 131 | break; 132 | default: 133 | orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; 134 | break; 135 | } 136 | } 137 | // if the device's natural orientation is landscape or if the device 138 | // is square: 139 | else { 140 | switch (rotation) { 141 | case Surface.ROTATION_0: 142 | orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; 143 | break; 144 | case Surface.ROTATION_90: 145 | orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; 146 | break; 147 | case Surface.ROTATION_180: 148 | orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; 149 | break; 150 | case Surface.ROTATION_270: 151 | orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; 152 | break; 153 | default: 154 | orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; 155 | break; 156 | } 157 | } 158 | 159 | return orientation; 160 | } 161 | } -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/widgets/MarqueeTextView.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.widgets; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.widget.TextView; 6 | 7 | /** 8 | * Created by Rukey7 on 2016/11/14. 9 | * 跑马灯TextView 10 | */ 11 | public class MarqueeTextView extends TextView { 12 | 13 | public MarqueeTextView(Context context) { 14 | super(context); 15 | } 16 | 17 | public MarqueeTextView(Context context, AttributeSet attrs) { 18 | super(context, attrs); 19 | } 20 | 21 | public MarqueeTextView(Context context, AttributeSet attrs, int defStyleAttr) { 22 | super(context, attrs, defStyleAttr); 23 | } 24 | 25 | @Override 26 | public boolean isFocused() { 27 | return true; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /playerview/src/main/java/com/dl7/player/widgets/ShareDialog.java: -------------------------------------------------------------------------------- 1 | package com.dl7.player.widgets; 2 | 3 | import android.content.DialogInterface; 4 | import android.graphics.Bitmap; 5 | import android.graphics.Color; 6 | import android.graphics.drawable.ColorDrawable; 7 | import android.net.Uri; 8 | import android.os.Bundle; 9 | import android.support.annotation.Nullable; 10 | import android.support.v4.app.DialogFragment; 11 | import android.view.LayoutInflater; 12 | import android.view.View; 13 | import android.view.ViewGroup; 14 | import android.view.Window; 15 | import android.view.WindowManager; 16 | import android.widget.ImageView; 17 | import android.widget.TextView; 18 | 19 | import com.dl7.player.R; 20 | 21 | /** 22 | * Created by long on 2016/11/17. 23 | */ 24 | 25 | public class ShareDialog extends DialogFragment { 26 | 27 | private OnDialogClickListener mClickListener; 28 | private OnDialogDismissListener mDismissListener; 29 | private Bitmap mBitmap; 30 | private boolean mIsShareMode = false; 31 | 32 | @Nullable 33 | @Override 34 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 35 | getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE); 36 | Window window = getDialog().getWindow(); 37 | window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); 38 | window.setWindowAnimations(R.style.AnimateDialog); 39 | window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); 40 | 41 | View view = inflater.inflate(R.layout.dialog_share, container); 42 | final ImageView photo = (ImageView) view.findViewById(R.id.iv_screenshot_photo); 43 | ViewGroup.LayoutParams layoutParams = photo.getLayoutParams(); 44 | layoutParams.width = getResources().getDisplayMetrics().widthPixels * 7 / 10; 45 | layoutParams.height = getResources().getDisplayMetrics().heightPixels * 7 / 10; 46 | photo.setLayoutParams(layoutParams); 47 | if (mBitmap != null) { 48 | photo.setImageBitmap(mBitmap); 49 | } 50 | view.findViewById(R.id.btn_cancel).setOnClickListener(new View.OnClickListener() { 51 | @Override 52 | public void onClick(View v) { 53 | dismiss(); 54 | } 55 | }); 56 | TextView tvShare = (TextView) view.findViewById(R.id.btn_share); 57 | if (mIsShareMode) { 58 | tvShare.setText("分享"); 59 | } 60 | tvShare.setOnClickListener(new View.OnClickListener() { 61 | @Override 62 | public void onClick(View v) { 63 | if (mClickListener != null) { 64 | mClickListener.onShare(mBitmap, null); 65 | } 66 | dismiss(); 67 | } 68 | }); 69 | return view; 70 | } 71 | 72 | @Override 73 | public void dismiss() { 74 | super.dismiss(); 75 | if (mDismissListener != null) { 76 | mDismissListener.onDismiss(); 77 | } 78 | } 79 | 80 | @Override 81 | public void onCancel(DialogInterface dialog) { 82 | super.onCancel(dialog); 83 | // 点击外部回调这里 84 | if (mDismissListener != null) { 85 | mDismissListener.onDismiss(); 86 | } 87 | } 88 | 89 | public void setScreenshotPhoto(Bitmap bitmap) { 90 | mBitmap = bitmap; 91 | } 92 | 93 | public void setClickListener(OnDialogClickListener clickListener) { 94 | mClickListener = clickListener; 95 | } 96 | 97 | public void setDismissListener(OnDialogDismissListener dismissListener) { 98 | mDismissListener = dismissListener; 99 | } 100 | 101 | public void setShareMode(boolean shareMode) { 102 | mIsShareMode = shareMode; 103 | } 104 | 105 | public interface OnDialogClickListener { 106 | void onShare(Bitmap bitmap, Uri uri); 107 | } 108 | 109 | public interface OnDialogDismissListener { 110 | void onDismiss(); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /playerview/src/main/res/anim/dialog_zoom_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 15 | -------------------------------------------------------------------------------- /playerview/src/main/res/anim/dialog_zoom_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/layer_battery_progress.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/layer_seek_progress.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_btn_ar_16_9.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_btn_ar_4_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_btn_ar_adjust_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_btn_ar_adjust_video.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_btn_danmaku_control.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_btn_danmaku_input_options_bottom_type.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_btn_danmaku_input_options_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_btn_danmaku_input_options_medium_textsize.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_btn_danmaku_input_options_rl_type.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_btn_danmaku_input_options_small_textsize.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_btn_danmaku_input_options_top_type.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_btn_fullscreen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_btn_play.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_btn_share_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_btn_share_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_item_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_media_quality_border.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_media_quality_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/sel_player_lock.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/shape_dialog_border.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/shape_player_lock_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/shape_seek_ball.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/shape_selected_border.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/shape_send_danmaku_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/shape_video_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /playerview/src/main/res/drawable/transition_item_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playerview/src/main/res/layout/adapter_media_quality.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 18 | -------------------------------------------------------------------------------- /playerview/src/main/res/layout/dialog_share.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 16 | 17 | 21 | 22 | 26 | 27 | 35 | 36 | 40 | 41 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /playerview/src/main/res/layout/layout_bottom_bar.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 21 | 22 | 36 | 37 | 44 | 45 | 53 | 54 | 62 | 63 | 73 | 74 | 85 | 86 | 95 | 96 | 111 | 112 | 123 | 124 | 140 | 141 | 150 | 151 | -------------------------------------------------------------------------------- /playerview/src/main/res/layout/layout_media_quality.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 14 | 15 | 21 | 22 | -------------------------------------------------------------------------------- /playerview/src/main/res/layout/layout_player_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 21 | 22 | 26 | 27 | 36 | 37 | 42 | 43 | 45 | 46 | 48 | 49 | 59 | 60 | 61 | 62 | 68 | 69 | 75 | 76 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /playerview/src/main/res/layout/layout_send_danmaku.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 14 | 15 | 19 | 20 | 30 | 31 | 41 | 42 | 50 | 51 | 52 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /playerview/src/main/res/layout/layout_skip_tip.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 15 | 16 | 23 | 24 | 28 | 29 | 36 | 37 | 44 | 45 | 49 | 50 | 59 | 60 | -------------------------------------------------------------------------------- /playerview/src/main/res/layout/layout_top_bar.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 14 | 15 | 22 | 23 | 38 | 39 | 44 | 45 | 52 | 53 | 60 | 61 | 73 | 74 | 75 | 81 | 82 | 89 | 90 | 91 | 102 | 103 | 107 | 108 | 112 | 113 | 117 | 118 | 122 | 123 | -------------------------------------------------------------------------------- /playerview/src/main/res/layout/layout_touch_gestures.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13 | 14 | 15 | 26 | 27 | 28 | 39 | 40 | 41 | 51 | 52 | 53 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_battery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_battery.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_battery_charging.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_battery_charging.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_battery_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_battery_red.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_brightness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_brightness.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_cancel_danmaku.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_cancel_danmaku.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_cancel_skip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_cancel_skip.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_danmaku_closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_danmaku_closed.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_danmaku_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_danmaku_open.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_fast_forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_fast_forward.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_fast_rewind.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_fast_rewind.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_fullscreen.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_fullscreen_exit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_fullscreen_exit.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_media_quality_bd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_media_quality_bd.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_media_quality_high.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_media_quality_high.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_media_quality_medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_media_quality_medium.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_media_quality_smooth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_media_quality_smooth.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_media_quality_super.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_media_quality_super.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_play_circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_play_circle.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_player_lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_player_lock.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_player_unlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_player_unlock.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_return_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_return_back.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_send_danmaku.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_send_danmaku.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_video_pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_video_pause.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_video_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_video_play.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_video_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_video_screenshot.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_volume_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_volume_off.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-hdpi/ic_volume_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-hdpi/ic_volume_on.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_ar_16_9_inside.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_ar_16_9_inside.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_ar_16_9_inside_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_ar_16_9_inside_checked.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_ar_4_3_inside.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_ar_4_3_inside.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_ar_4_3_inside_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_ar_4_3_inside_checked.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_ar_adjust_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_ar_adjust_screen.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_ar_adjust_screen_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_ar_adjust_screen_checked.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_ar_adjust_video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_ar_adjust_video.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_ar_adjust_video_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_ar_adjust_video_checked.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_brightness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_brightness.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_btn_danmaku_input_options_color_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_btn_danmaku_input_options_color_checked.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_cancel_danmaku.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_cancel_danmaku.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_cancel_skip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_cancel_skip.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_danmaku_closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_danmaku_closed.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_more_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_more_color.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_bottom_type.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_bottom_type.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_bottom_type_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_bottom_type_checked.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_medium_textsize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_medium_textsize.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_medium_textsize_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_medium_textsize_checked.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_rl_type.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_rl_type.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_rl_type_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_rl_type_checked.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_small_textsize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_small_textsize.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_small_textsize_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_small_textsize_checked.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_top_type.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_top_type.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_top_type_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_danmaku_input_options_top_type_checked.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_danmaku_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_danmaku_open.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_fast_forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_fast_forward.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_fast_rewind.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_fast_rewind.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_fullscreen.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_fullscreen_exit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_fullscreen_exit.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_media_quality_bd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_media_quality_bd.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_media_quality_high.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_media_quality_high.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_media_quality_medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_media_quality_medium.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_media_quality_smooth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_media_quality_smooth.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_media_quality_super.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_media_quality_super.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_play_circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_play_circle.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_player_lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_player_lock.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_player_unlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_player_unlock.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_reload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_reload.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_return_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_return_back.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_send_danmaku.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_send_danmaku.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_video_pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_video_pause.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_video_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_video_play.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_video_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_video_screenshot.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_volume_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_volume_off.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xhdpi/ic_volume_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xhdpi/ic_volume_on.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_brightness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_brightness.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_cancel_danmaku.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_cancel_danmaku.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_cancel_skip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_cancel_skip.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_danmaku_closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_danmaku_closed.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_danmaku_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_danmaku_open.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_fast_forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_fast_forward.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_fast_rewind.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_fast_rewind.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_fullscreen.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_fullscreen_exit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_fullscreen_exit.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_media_quality_bd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_media_quality_bd.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_media_quality_high.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_media_quality_high.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_media_quality_medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_media_quality_medium.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_media_quality_smooth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_media_quality_smooth.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_media_quality_super.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_media_quality_super.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_play_circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_play_circle.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_player_lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_player_lock.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_player_unlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_player_unlock.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_return_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_return_back.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_send_danmaku.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_send_danmaku.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_video_pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_video_pause.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_video_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_video_play.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_video_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_video_screenshot.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_volume_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_volume_off.png -------------------------------------------------------------------------------- /playerview/src/main/res/mipmap-xxhdpi/ic_volume_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rukey7/IjkPlayerView/a2ce0666d0f5147bdde3621fb2fd8d753eddbc64/playerview/src/main/res/mipmap-xxhdpi/ic_volume_on.png -------------------------------------------------------------------------------- /playerview/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | #80000000 6 | 7 | #809e9e9e 8 | #cce91e63 9 | #88f48fb1 10 | #ffffffff 11 | 12 | #ccec407a 13 | #e91e63 14 | 15 | #55ffffff 16 | #ffffff 17 | 18 | #ffa5a5a5 19 | #ffbababa 20 | 21 | #f06292 22 | 23 | -------------------------------------------------------------------------------- /playerview/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 46dp 5 | 48dp 6 | 32.0dip 7 | 25.0dip 8 | 5.0dip 9 | 42.0dip 10 | 11 | 44dp 12 | 20dp 13 | 30dp 14 | -------------------------------------------------------------------------------- /playerview/src/main/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | false 5 | false 6 | false 7 | false 8 | false 9 | false 10 | false 11 | false 12 | false 13 | false 14 | false 15 | false 16 | false 17 | false 18 | false 19 | false 20 | false 21 | false 22 | false 23 | false 24 | false 25 | false 26 | false 27 | false 28 | 29 | false 30 | -------------------------------------------------------------------------------- /playerview/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | PlayerView 3 | 记忆上次播放到 4 | 继续播放 5 | 6 | 7 | 流畅 8 | 清晰 9 | 高清 10 | 超清 11 | 1080P 12 | 13 | 14 | -------------------------------------------------------------------------------- /playerview/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 17 | 18 | 19 | 28 | 29 | 30 | 37 | 38 | 39 | 45 | 46 | 47 | 51 | -------------------------------------------------------------------------------- /playerview/src/test/java/com/dl7/player/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.dl7.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() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /sample/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion "24.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.dl7.player" 9 | minSdkVersion 15 10 | targetSdkVersion 24 11 | versionCode 1 12 | versionName "1.0" 13 | 14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 15 | 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | } 24 | 25 | dependencies { 26 | compile fileTree(include: ['*.jar'], dir: 'libs') 27 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 28 | exclude group: 'com.android.support', module: 'support-annotations' 29 | }) 30 | compile 'com.android.support:appcompat-v7:24.2.0' 31 | compile 'com.android.support:design:24.2.0' 32 | compile 'com.android.support:cardview-v7:24.2.0' 33 | testCompile 'junit:junit:4.12' 34 | compile project(':playerview') 35 | compile 'com.github.bumptech.glide:glide:3.7.0' 36 | compile 'com.google.code.gson:gson:2.2.4' 37 | // TagLayout 38 | compile 'com.github.Rukey7:TagLayout:1.0.3' 39 | } 40 | -------------------------------------------------------------------------------- /sample/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in F:\WorkTools\Android\SDK/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /sample/src/androidTest/java/com/dl7/playerdemo/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.dl7.playerdemo; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.dl7.nativeplayer", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /sample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 17 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 36 | 37 | 41 | 42 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /sample/src/main/java/com/dl7/playerdemo/IjkFullscreenActivity.java: -------------------------------------------------------------------------------- 1 | package com.dl7.playerdemo; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.view.KeyEvent; 6 | 7 | import com.bumptech.glide.Glide; 8 | import com.dl7.player.media.IjkPlayerView; 9 | 10 | public class IjkFullscreenActivity extends AppCompatActivity { 11 | 12 | private static final String VIDEO_URL = "http://flv2.bn.netease.com/videolib3/1611/28/nNTov5571/SD/nNTov5571-mobile.mp4"; 13 | private static final String IMAGE_URL = "http://vimg3.ws.126.net/image/snapshot/2016/11/C/T/VC628QHCT.jpg"; 14 | IjkPlayerView mPlayerView; 15 | 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | mPlayerView = new IjkPlayerView(this); 20 | setContentView(mPlayerView); 21 | Glide.with(this).load(IMAGE_URL).fitCenter().into(mPlayerView.mPlayerThumb); 22 | mPlayerView.init() 23 | .alwaysFullScreen() 24 | .enableOrientation() 25 | .setVideoPath(VIDEO_URL) 26 | .enableDanmaku() 27 | .setDanmakuSource(getResources().openRawResource(R.raw.bili)) 28 | .setTitle("这是个跑马灯TextView,标题要足够长才会跑。-(゜ -゜)つロ 乾杯~") 29 | .start(); 30 | } 31 | 32 | @Override 33 | protected void onResume() { 34 | super.onResume(); 35 | mPlayerView.onResume(); 36 | } 37 | 38 | @Override 39 | protected void onPause() { 40 | super.onPause(); 41 | mPlayerView.onPause(); 42 | } 43 | 44 | @Override 45 | protected void onDestroy() { 46 | super.onDestroy(); 47 | mPlayerView.onDestroy(); 48 | } 49 | 50 | @Override 51 | public boolean onKeyDown(int keyCode, KeyEvent event) { 52 | if (mPlayerView.handleVolumeKey(keyCode)) { 53 | return true; 54 | } 55 | return super.onKeyDown(keyCode, event); 56 | } 57 | 58 | @Override 59 | public void onBackPressed() { 60 | if (mPlayerView.onBackPressed()) { 61 | return; 62 | } 63 | super.onBackPressed(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /sample/src/main/java/com/dl7/playerdemo/IjkPlayerActivity.java: -------------------------------------------------------------------------------- 1 | package com.dl7.playerdemo; 2 | 3 | import android.content.res.Configuration; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.Toolbar; 7 | import android.view.KeyEvent; 8 | import android.view.MotionEvent; 9 | import android.view.View; 10 | import android.widget.Button; 11 | import android.widget.EditText; 12 | 13 | import com.bumptech.glide.Glide; 14 | import com.dl7.player.media.IjkPlayerView; 15 | import com.dl7.player.utils.SoftInputUtils; 16 | 17 | public class IjkPlayerActivity extends AppCompatActivity { 18 | 19 | private static final String VIDEO_URL = "http://flv2.bn.netease.com/videolib3/1611/28/GbgsL3639/SD/movie_index.m3u8"; 20 | private static final String VIDEO_HD_URL = "http://flv2.bn.netease.com/videolib3/1611/28/GbgsL3639/HD/movie_index.m3u8"; 21 | private static final String IMAGE_URL = "http://vimg2.ws.126.net/image/snapshot/2016/11/I/M/VC62HMUIM.jpg"; 22 | 23 | Toolbar mToolbar; 24 | private IjkPlayerView mPlayerView; 25 | private View mEtLayout; 26 | private EditText mEditText; 27 | private Button mIvSend; 28 | private boolean mIsFocus; 29 | 30 | @Override 31 | protected void onCreate(Bundle savedInstanceState) { 32 | super.onCreate(savedInstanceState); 33 | setContentView(R.layout.activity_ijk_player); 34 | mToolbar = (Toolbar) findViewById(R.id.toolbar); 35 | mPlayerView = (IjkPlayerView) findViewById(R.id.player_view); 36 | mEtLayout = findViewById(R.id.ll_layout); 37 | mEditText = (EditText) findViewById(R.id.et_content); 38 | mIvSend = (Button) findViewById(R.id.btn_send); 39 | setSupportActionBar(mToolbar); 40 | mToolbar.setTitle("Video Player"); 41 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 42 | 43 | Glide.with(this).load(IMAGE_URL).fitCenter().into(mPlayerView.mPlayerThumb); 44 | mPlayerView.init() 45 | .setTitle("这是个跑马灯TextView,标题要足够长才会跑。-(゜ -゜)つロ 乾杯~") 46 | .setSkipTip(1000*60*1) 47 | .enableDanmaku() 48 | .setDanmakuSource(getResources().openRawResource(R.raw.bili)) 49 | .setVideoSource(null, VIDEO_URL, VIDEO_HD_URL, null, null) 50 | .setMediaQuality(IjkPlayerView.MEDIA_QUALITY_HIGH); 51 | 52 | mIvSend.setOnClickListener(new View.OnClickListener() { 53 | @Override 54 | public void onClick(View v) { 55 | mPlayerView.sendDanmaku(mEditText.getText().toString(), false); 56 | mEditText.setText(""); 57 | _closeSoftInput(); 58 | } 59 | }); 60 | mEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() { 61 | @Override 62 | public void onFocusChange(View view, boolean isFocus) { 63 | if (isFocus) { 64 | mPlayerView.editVideo(); 65 | } 66 | mIsFocus = isFocus; 67 | } 68 | }); 69 | } 70 | 71 | @Override 72 | protected void onResume() { 73 | super.onResume(); 74 | mPlayerView.onResume(); 75 | } 76 | 77 | @Override 78 | protected void onPause() { 79 | super.onPause(); 80 | mPlayerView.onPause(); 81 | } 82 | 83 | @Override 84 | protected void onDestroy() { 85 | super.onDestroy(); 86 | mPlayerView.onDestroy(); 87 | } 88 | 89 | @Override 90 | public void onConfigurationChanged(Configuration newConfig) { 91 | super.onConfigurationChanged(newConfig); 92 | mPlayerView.configurationChanged(newConfig); 93 | } 94 | 95 | @Override 96 | public boolean onKeyDown(int keyCode, KeyEvent event) { 97 | if (mPlayerView.handleVolumeKey(keyCode)) { 98 | return true; 99 | } 100 | return super.onKeyDown(keyCode, event); 101 | } 102 | 103 | @Override 104 | public void onBackPressed() { 105 | if (mPlayerView.onBackPressed()) { 106 | return; 107 | } 108 | super.onBackPressed(); 109 | } 110 | 111 | 112 | 113 | @Override 114 | public boolean dispatchTouchEvent(MotionEvent ev) { 115 | View view = getCurrentFocus(); 116 | if (_isHideSoftInput(view, (int) ev.getX(), (int) ev.getY())) { 117 | _closeSoftInput(); 118 | return true; 119 | } 120 | return super.dispatchTouchEvent(ev); 121 | } 122 | 123 | private void _closeSoftInput() { 124 | mEditText.clearFocus(); 125 | SoftInputUtils.closeSoftInput(this); 126 | mPlayerView.recoverFromEditVideo(); 127 | } 128 | 129 | private boolean _isHideSoftInput(View view, int x, int y) { 130 | if (view == null || !(view instanceof EditText) || !mIsFocus) { 131 | return false; 132 | } 133 | return x < mEtLayout.getLeft() || 134 | x > mEtLayout.getRight() || 135 | y < mEtLayout.getTop(); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /sample/src/main/java/com/dl7/playerdemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.dl7.playerdemo; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.View; 7 | 8 | public class MainActivity extends AppCompatActivity { 9 | 10 | @Override 11 | protected void onCreate(Bundle savedInstanceState) { 12 | super.onCreate(savedInstanceState); 13 | setContentView(R.layout.activity_main); 14 | 15 | findViewById(R.id.btn_video).setOnClickListener(new View.OnClickListener() { 16 | @Override 17 | public void onClick(View v) { 18 | startActivity(new Intent(MainActivity.this, IjkPlayerActivity.class)); 19 | } 20 | }); 21 | findViewById(R.id.btn_fullscreen_video).setOnClickListener(new View.OnClickListener() { 22 | @Override 23 | public void onClick(View v) { 24 | startActivity(new Intent(MainActivity.this, IjkFullscreenActivity.class)); 25 | } 26 | }); 27 | findViewById(R.id.btn_test_aspect).setOnClickListener(new View.OnClickListener() { 28 | @Override 29 | public void onClick(View v) { 30 | startActivity(new Intent(MainActivity.this, TestAspectActivity.class)); 31 | } 32 | }); 33 | findViewById(R.id.btn_custom_danmaku).setOnClickListener(new View.OnClickListener() { 34 | @Override 35 | public void onClick(View v) { 36 | startActivity(new Intent(MainActivity.this, CustomDanmakuActivity.class)); 37 | } 38 | }); 39 | findViewById(R.id.btn_switch_video).setOnClickListener(new View.OnClickListener() { 40 | @Override 41 | public void onClick(View v) { 42 | startActivity(new Intent(MainActivity.this, SwitchVideoActivity.class)); 43 | } 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /sample/src/main/java/com/dl7/playerdemo/SwitchVideoActivity.java: -------------------------------------------------------------------------------- 1 | package com.dl7.playerdemo; 2 | 3 | import android.content.res.Configuration; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.KeyEvent; 7 | 8 | import com.bumptech.glide.Glide; 9 | import com.dl7.player.media.IjkPlayerView; 10 | import com.dl7.tag.TagLayout; 11 | import com.dl7.tag.TagView; 12 | 13 | import tv.danmaku.ijk.media.player.IMediaPlayer; 14 | 15 | public class SwitchVideoActivity extends AppCompatActivity { 16 | 17 | private static final String IMAGE_URL = "http://vimg3.ws.126.net/image/snapshot/2015/5/J/M/VAPRJCSJM.jpg"; 18 | 19 | private final String[] mVideoPath = new String[]{ 20 | "http://flv2.bn.netease.com/videolib3/1505/29/DCNOo7461/SD/DCNOo7461-mobile.mp4", 21 | "http://flv2.bn.netease.com/videolib3/1611/28/nNTov5571/SD/nNTov5571-mobile.mp4", 22 | "http://flv2.bn.netease.com/videolib3/1611/28/GbgsL3639/SD/movie_index.m3u8", 23 | }; 24 | private final String[] mTitle = new String[]{ 25 | "视频1", "视频2", "视频3", 26 | }; 27 | 28 | private IjkPlayerView mPlayerView; 29 | private TagLayout mTagLayout; 30 | private int mIndex = 0; 31 | 32 | @Override 33 | protected void onCreate(Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | setContentView(R.layout.activity_switch_video); 36 | mPlayerView = (IjkPlayerView) findViewById(R.id.player_view); 37 | mTagLayout = (TagLayout) findViewById(R.id.tag_layout); 38 | 39 | Glide.with(this).load(IMAGE_URL).fitCenter().into(mPlayerView.mPlayerThumb); 40 | mPlayerView.init() 41 | .setTitle(mTitle[mIndex]) 42 | .enableDanmaku() 43 | .setDanmakuSource(getResources().openRawResource(R.raw.bili)) 44 | .setVideoPath(mVideoPath[mIndex]); 45 | 46 | mPlayerView.setOnCompletionListener(new IMediaPlayer.OnCompletionListener() { 47 | @Override 48 | public void onCompletion(IMediaPlayer iMediaPlayer) { 49 | mIndex++; 50 | if (mIndex != mTitle.length) { 51 | mPlayerView.switchVideoPath(mVideoPath[mIndex]) 52 | .setTitle(mTitle[mIndex]) 53 | .enableDanmaku(false) 54 | .start(); 55 | mTagLayout.setCheckTag(mIndex); 56 | } 57 | } 58 | }); 59 | 60 | mTagLayout.setTags(mTitle); 61 | mTagLayout.setCheckTag(0); 62 | mTagLayout.setTagCheckListener(new TagView.OnTagCheckListener() { 63 | @Override 64 | public void onTagCheck(int i, String s, boolean isCheck) { 65 | if (isCheck && mIndex != i) { 66 | mIndex = i; 67 | mPlayerView.switchVideoPath(mVideoPath[mIndex]) 68 | .setTitle(mTitle[mIndex]) 69 | .enableDanmaku() 70 | .setDanmakuSource(getResources().openRawResource(R.raw.bili)) 71 | .start(); 72 | } 73 | } 74 | }); 75 | } 76 | 77 | @Override 78 | protected void onResume() { 79 | super.onResume(); 80 | mPlayerView.onResume(); 81 | } 82 | 83 | @Override 84 | protected void onPause() { 85 | super.onPause(); 86 | mPlayerView.onPause(); 87 | } 88 | 89 | @Override 90 | protected void onDestroy() { 91 | super.onDestroy(); 92 | mPlayerView.onDestroy(); 93 | } 94 | 95 | @Override 96 | public void onConfigurationChanged(Configuration newConfig) { 97 | super.onConfigurationChanged(newConfig); 98 | mPlayerView.configurationChanged(newConfig); 99 | } 100 | 101 | @Override 102 | public boolean onKeyDown(int keyCode, KeyEvent event) { 103 | if (mPlayerView.handleVolumeKey(keyCode)) { 104 | return true; 105 | } 106 | return super.onKeyDown(keyCode, event); 107 | } 108 | 109 | @Override 110 | public void onBackPressed() { 111 | if (mPlayerView.onBackPressed()) { 112 | return; 113 | } 114 | super.onBackPressed(); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /sample/src/main/java/com/dl7/playerdemo/TestAspectActivity.java: -------------------------------------------------------------------------------- 1 | package com.dl7.playerdemo; 2 | 3 | import android.content.res.Configuration; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.KeyEvent; 7 | import android.widget.ListView; 8 | 9 | import com.bumptech.glide.Glide; 10 | import com.dl7.player.media.IjkPlayerView; 11 | import com.dl7.playerdemo.adapter.ListAdapter; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | public class TestAspectActivity extends AppCompatActivity { 17 | 18 | private static final String VIDEO_URL = "http://flv2.bn.netease.com/videolib3/1505/29/DCNOo7461/SD/DCNOo7461-mobile.mp4"; 19 | private static final String IMAGE_URL = "http://vimg3.ws.126.net/image/snapshot/2015/5/J/M/VAPRJCSJM.jpg"; 20 | 21 | private IjkPlayerView mPlayerView; 22 | private ListView mListView; 23 | private ListAdapter mAdapter; 24 | 25 | @Override 26 | protected void onCreate(Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | setContentView(R.layout.activity_test_aspect); 29 | mPlayerView = (IjkPlayerView) findViewById(R.id.player_view); 30 | mListView = (ListView) findViewById(R.id.lv_list); 31 | 32 | List list = new ArrayList<>(); 33 | for (int i = 0; i < 40; i++) { 34 | list.add("Some message " + i); 35 | } 36 | mAdapter = new ListAdapter(this, list); 37 | mListView.setAdapter(mAdapter); 38 | 39 | Glide.with(this).load(IMAGE_URL).fitCenter().into(mPlayerView.mPlayerThumb); 40 | mPlayerView.init() 41 | .setTitle("美加州死亡谷石头会走路") 42 | .setVideoPath(VIDEO_URL); 43 | } 44 | 45 | @Override 46 | protected void onResume() { 47 | super.onResume(); 48 | mPlayerView.onResume(); 49 | } 50 | 51 | @Override 52 | protected void onPause() { 53 | super.onPause(); 54 | mPlayerView.onPause(); 55 | } 56 | 57 | @Override 58 | protected void onDestroy() { 59 | super.onDestroy(); 60 | mPlayerView.onDestroy(); 61 | } 62 | 63 | @Override 64 | public void onConfigurationChanged(Configuration newConfig) { 65 | super.onConfigurationChanged(newConfig); 66 | mPlayerView.configurationChanged(newConfig); 67 | } 68 | 69 | @Override 70 | public boolean onKeyDown(int keyCode, KeyEvent event) { 71 | if (mPlayerView.handleVolumeKey(keyCode)) { 72 | return true; 73 | } 74 | return super.onKeyDown(keyCode, event); 75 | } 76 | 77 | @Override 78 | public void onBackPressed() { 79 | if (mPlayerView.onBackPressed()) { 80 | return; 81 | } 82 | super.onBackPressed(); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /sample/src/main/java/com/dl7/playerdemo/adapter/BaseListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.dl7.playerdemo.adapter; 2 | 3 | import android.content.Context; 4 | import android.widget.BaseAdapter; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | /** 11 | * Created by long on 2016/6/7. 12 | * ListView的基础适配器 13 | */ 14 | public abstract class BaseListAdapter extends BaseAdapter { 15 | 16 | protected Context mContext; 17 | protected List mDatas; 18 | 19 | 20 | public BaseListAdapter(Context context) { 21 | this.mContext = context; 22 | this.mDatas = new ArrayList<>(); 23 | } 24 | 25 | public BaseListAdapter(Context context, List datas) { 26 | this.mContext = context; 27 | this.mDatas = datas; 28 | } 29 | 30 | public BaseListAdapter(Context context, T[] datas) { 31 | this.mContext = context; 32 | this.mDatas = new ArrayList(); 33 | Collections.addAll(mDatas, datas); 34 | } 35 | 36 | 37 | @Override 38 | public int getCount() { 39 | return mDatas.size(); 40 | } 41 | 42 | @Override 43 | public T getItem(int position) { 44 | return mDatas.get(position); 45 | } 46 | 47 | @Override 48 | public long getItemId(int position) { 49 | return position; 50 | } 51 | 52 | 53 | 54 | /** 55 | * 更新数据,替换原有数据 56 | * @param items 57 | */ 58 | public void updateItems(List items) { 59 | mDatas = items; 60 | notifyDataSetChanged(); 61 | } 62 | 63 | /** 64 | * 插入一条数据 65 | * @param item 数据 66 | */ 67 | public void addItem(T item) { 68 | mDatas.add(0, item); 69 | notifyDataSetChanged(); 70 | } 71 | 72 | /** 73 | * 插入一条数据 74 | * @param item 数据 75 | * @param position 插入位置 76 | */ 77 | public void addItem(T item, int position) { 78 | position = Math.min(position, mDatas.size()); 79 | mDatas.add(position, item); 80 | notifyDataSetChanged(); 81 | } 82 | 83 | /** 84 | * 在列表尾添加一串数据 85 | * @param items 86 | */ 87 | public void addItems(List items) { 88 | mDatas.addAll(items); 89 | } 90 | 91 | /** 92 | * 移除一条数据 93 | * @param position 位置 94 | */ 95 | public void removeItem(int position) { 96 | if (position > mDatas.size() - 1) { 97 | return; 98 | } 99 | mDatas.remove(position); 100 | notifyDataSetChanged(); 101 | } 102 | 103 | /** 104 | * 移除一条数据 105 | * @param item 数据 106 | */ 107 | public void removeItem(T item) { 108 | int pos = 0; 109 | for (T info : mDatas) { 110 | if (item.hashCode() == info.hashCode()) { 111 | removeItem(pos); 112 | break; 113 | } 114 | pos++; 115 | } 116 | } 117 | 118 | /** 119 | * 清除所有数据 120 | */ 121 | public void cleanItems() { 122 | mDatas.clear(); 123 | notifyDataSetChanged(); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /sample/src/main/java/com/dl7/playerdemo/adapter/ListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.dl7.playerdemo.adapter; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.TextView; 8 | 9 | import com.dl7.playerdemo.R; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * Created by Rukey7 on 2016/11/27. 15 | */ 16 | 17 | public class ListAdapter extends BaseListAdapter { 18 | 19 | public ListAdapter(Context context) { 20 | super(context); 21 | } 22 | 23 | public ListAdapter(Context context, List datas) { 24 | super(context, datas); 25 | } 26 | 27 | @Override 28 | public View getView(int i, View view, ViewGroup viewGroup) { 29 | if (view == null) { 30 | view = LayoutInflater.from(mContext).inflate(R.layout.adapter_list, viewGroup, false); 31 | } 32 | TextView tvContent = (TextView) view.findViewById(R.id.tv_content); 33 | tvContent.setText(mDatas.get(i)); 34 | return view; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /sample/src/main/java/com/dl7/playerdemo/danmaku/DanmakuConverter.java: -------------------------------------------------------------------------------- 1 | package com.dl7.playerdemo.danmaku; 2 | 3 | import com.dl7.player.danmaku.BaseDanmakuConverter; 4 | 5 | import master.flame.danmaku.danmaku.model.BaseDanmaku; 6 | 7 | /** 8 | * Created by long on 2016/12/22. 9 | * 弹幕数据转换器 10 | */ 11 | public class DanmakuConverter extends BaseDanmakuConverter { 12 | 13 | private DanmakuConverter(){} 14 | private static volatile DanmakuConverter instance; 15 | 16 | public static DanmakuConverter instance() { 17 | if(instance == null){ 18 | synchronized (DanmakuConverter.class){ 19 | if(instance == null) 20 | instance = new DanmakuConverter(); 21 | } 22 | } 23 | return instance; 24 | } 25 | 26 | @Override 27 | public DanmakuData convertDanmaku(BaseDanmaku danmaku) { 28 | DanmakuData data = new DanmakuData(); 29 | // 弹幕基础数据初始化,重要!记得调用 30 | initData(data, danmaku); 31 | return data; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /sample/src/main/java/com/dl7/playerdemo/danmaku/DanmakuData.java: -------------------------------------------------------------------------------- 1 | package com.dl7.playerdemo.danmaku; 2 | 3 | import com.dl7.player.danmaku.BaseDanmakuData; 4 | 5 | /** 6 | * Created by long on 2016/12/22. 7 | * 自定义弹幕数据 8 | */ 9 | public class DanmakuData extends BaseDanmakuData { 10 | 11 | // 用户名 12 | public String userName; 13 | // 用户等级 14 | public int userLevel; 15 | 16 | @Override 17 | public String toString() { 18 | return "DanmakuData{" + 19 | "userName='" + userName + '\'' + 20 | ", userLevel=" + userLevel + 21 | "} " + super.toString(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /sample/src/main/java/com/dl7/playerdemo/danmaku/DanmakuLoader.java: -------------------------------------------------------------------------------- 1 | package com.dl7.playerdemo.danmaku; 2 | 3 | import android.net.Uri; 4 | 5 | import java.io.InputStream; 6 | 7 | import master.flame.danmaku.danmaku.loader.ILoader; 8 | import master.flame.danmaku.danmaku.loader.IllegalDataException; 9 | 10 | /** 11 | * Created by long on 2016/12/22. 12 | * 自定义弹幕加载器,参考A站 13 | */ 14 | public class DanmakuLoader implements ILoader { 15 | 16 | private DanmakuLoader(){} 17 | private static volatile DanmakuLoader instance; 18 | private JsonStrSource dataSource; 19 | 20 | public static ILoader instance() { 21 | if(instance == null){ 22 | synchronized (DanmakuLoader.class){ 23 | if(instance == null) 24 | instance = new DanmakuLoader(); 25 | } 26 | } 27 | return instance; 28 | } 29 | 30 | @Override 31 | public JsonStrSource getDataSource() { 32 | return dataSource; 33 | } 34 | 35 | @Override 36 | public void load(String uri) throws IllegalDataException { 37 | try { 38 | dataSource = new JsonStrSource(Uri.parse(uri)); 39 | } catch (Exception e) { 40 | throw new IllegalDataException(e); 41 | } 42 | } 43 | 44 | @Override 45 | public void load(InputStream in) throws IllegalDataException { 46 | try { 47 | dataSource = new JsonStrSource(in); 48 | } catch (Exception e) { 49 | throw new IllegalDataException(e); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /sample/src/main/java/com/dl7/playerdemo/danmaku/DanmakuParser.java: -------------------------------------------------------------------------------- 1 | package com.dl7.playerdemo.danmaku; 2 | 3 | import android.graphics.Color; 4 | import android.text.TextUtils; 5 | 6 | import com.dl7.playerdemo.utils.GsonHelper; 7 | 8 | import java.util.List; 9 | 10 | import master.flame.danmaku.danmaku.model.BaseDanmaku; 11 | import master.flame.danmaku.danmaku.model.IDanmakus; 12 | import master.flame.danmaku.danmaku.model.android.Danmakus; 13 | import master.flame.danmaku.danmaku.parser.BaseDanmakuParser; 14 | import master.flame.danmaku.danmaku.util.DanmakuUtils; 15 | 16 | import static android.R.attr.textColor; 17 | 18 | /** 19 | * Created by long on 2016/12/22. 20 | * 自定义弹幕解析器,参考A站 21 | */ 22 | public class DanmakuParser extends BaseDanmakuParser { 23 | 24 | @Override 25 | protected IDanmakus parse() { 26 | if (mDataSource != null && mDataSource instanceof JsonStrSource) { 27 | JsonStrSource jsonSource = (JsonStrSource) mDataSource; 28 | return doParse(jsonSource.data()); 29 | } 30 | return new Danmakus(); 31 | } 32 | 33 | /** 34 | * @param jsonStr 弹幕数据 35 | * @return 转换后的Danmakus 36 | */ 37 | private Danmakus doParse(String jsonStr) { 38 | Danmakus danmakus = new Danmakus(); 39 | if (TextUtils.isEmpty(jsonStr)) { 40 | return danmakus; 41 | } 42 | try { 43 | List datas = GsonHelper.convertEntities(jsonStr, DanmakuData.class); 44 | int size = datas.size(); 45 | for (int i = 0; i < size; i++) { 46 | BaseDanmaku item = mContext.mDanmakuFactory.createDanmaku(datas.get(i).getType(), mContext); 47 | if (item != null) { 48 | item.setTime(datas.get(i).getTime()); 49 | item.textSize = datas.get(i).getTextSize(); 50 | item.textColor = datas.get(i).getTextColor(); 51 | item.textShadowColor = textColor <= Color.BLACK ? Color.WHITE : Color.BLACK; 52 | DanmakuUtils.fillText(item, datas.get(i).getContent()); 53 | item.index = i; 54 | item.setTimer(mTimer); 55 | danmakus.addItem(item); 56 | } 57 | } 58 | } catch (Exception e) { 59 | e.printStackTrace(); 60 | } 61 | 62 | return danmakus; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /sample/src/main/java/com/dl7/playerdemo/danmaku/JsonStrSource.java: -------------------------------------------------------------------------------- 1 | package com.dl7.playerdemo.danmaku; 2 | 3 | import android.net.Uri; 4 | import android.text.TextUtils; 5 | 6 | import org.json.JSONException; 7 | 8 | import java.io.File; 9 | import java.io.FileInputStream; 10 | import java.io.FileNotFoundException; 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.net.URL; 14 | 15 | import master.flame.danmaku.danmaku.parser.IDataSource; 16 | import master.flame.danmaku.danmaku.util.IOUtils; 17 | 18 | /** 19 | * Created by long on 2016/12/22. 20 | * 自定义弹幕数据源,参考A站 21 | */ 22 | public class JsonStrSource implements IDataSource { 23 | 24 | private String mJsonStr; 25 | private InputStream mInput; 26 | public JsonStrSource(String json) throws JSONException{ 27 | init(json); 28 | } 29 | 30 | public JsonStrSource(InputStream in) throws JSONException{ 31 | init(in); 32 | } 33 | 34 | private void init(InputStream in) throws JSONException { 35 | if(in == null) 36 | throw new NullPointerException("input stream cannot be null!"); 37 | mInput = in; 38 | String json = IOUtils.getString(mInput); 39 | init(json); 40 | } 41 | 42 | public JsonStrSource(URL url) throws JSONException, IOException { 43 | this(url.openStream()); 44 | } 45 | 46 | public JsonStrSource(File file) throws FileNotFoundException, JSONException{ 47 | init(new FileInputStream(file)); 48 | } 49 | 50 | public JsonStrSource(Uri uri) throws IOException, JSONException { 51 | String scheme = uri.getScheme(); 52 | if (SCHEME_HTTP_TAG.equalsIgnoreCase(scheme) || SCHEME_HTTPS_TAG.equalsIgnoreCase(scheme)) { 53 | init(new URL(uri.getPath()).openStream()); 54 | } else if (SCHEME_FILE_TAG.equalsIgnoreCase(scheme)) { 55 | init(new FileInputStream(uri.getPath())); 56 | } 57 | } 58 | 59 | private void init(String json) throws JSONException { 60 | if(!TextUtils.isEmpty(json)){ 61 | mJsonStr = json; 62 | } 63 | } 64 | 65 | @Override 66 | public String data(){ 67 | return mJsonStr; 68 | } 69 | 70 | @Override 71 | public void release() { 72 | IOUtils.closeQuietly(mInput); 73 | mInput = null; 74 | mJsonStr = null; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /sample/src/main/java/com/dl7/playerdemo/utils/AfunData.java: -------------------------------------------------------------------------------- 1 | package com.dl7.playerdemo.utils; 2 | 3 | /** 4 | * Created by long on 2016/12/22. 5 | */ 6 | 7 | public class AfunData { 8 | 9 | /** 10 | * c : 0,16777215,1,25,196050,1364468342 11 | * m : 。。。。。。。。。。。。。。。。。。。。。。 12 | */ 13 | 14 | private String c; 15 | private String m; 16 | 17 | public String getC() { 18 | return c; 19 | } 20 | 21 | public void setC(String c) { 22 | this.c = c; 23 | } 24 | 25 | public String getM() { 26 | return m; 27 | } 28 | 29 | public void setM(String m) { 30 | this.m = m; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /sample/src/main/java/com/dl7/playerdemo/utils/AssetsHelper.java: -------------------------------------------------------------------------------- 1 | package com.dl7.playerdemo.utils; 2 | 3 | import android.content.Context; 4 | 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | 8 | /** 9 | * Created by long on 2016/6/28. 10 | * Assets帮助类,测试用 11 | */ 12 | public class AssetsHelper { 13 | 14 | private AssetsHelper() { 15 | } 16 | 17 | 18 | public static String readData(Context context, String fileName) { 19 | InputStream inStream = null; 20 | String data = null; 21 | try { 22 | inStream = context.getAssets().open(fileName); //打开assets目录中的文本文件 23 | byte[] bytes = new byte[inStream.available()]; //inStream.available()为文件中的总byte数 24 | inStream.read(bytes); 25 | inStream.close(); 26 | data = new String(bytes, "utf-8"); //将bytes转为utf-8字符串 27 | } catch (IOException e) { 28 | e.printStackTrace(); 29 | } 30 | return data; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /sample/src/main/java/com/dl7/playerdemo/utils/GsonHelper.java: -------------------------------------------------------------------------------- 1 | package com.dl7.playerdemo.utils; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.JsonArray; 5 | import com.google.gson.JsonElement; 6 | import com.google.gson.JsonParser; 7 | import com.google.gson.JsonSyntaxException; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | /** 13 | * Created by long on 2016/5/9. 14 | * Gson数据转化处理 15 | */ 16 | public final class GsonHelper { 17 | 18 | private static Gson sGson = new Gson(); 19 | private static JsonParser sJsonParser = new JsonParser(); 20 | 21 | 22 | /** 23 | * 将json数据转化为实体数据 24 | * @param jsonData json字符串 25 | * @param entityClass 类型 26 | * @return 实体 27 | */ 28 | public static T convertEntity(String jsonData, Class entityClass) { 29 | T entity = null; 30 | try { 31 | entity = sGson.fromJson(jsonData, entityClass); 32 | } catch (JsonSyntaxException e) { 33 | e.printStackTrace(); 34 | } 35 | return entity; 36 | } 37 | 38 | /** 39 | * 将json数据转化为实体列表数据 40 | * @param jsonData json字符串 41 | * @param entityClass 类型 42 | * @return 实体列表 43 | */ 44 | public static List convertEntities(String jsonData, Class entityClass) { 45 | List entities = new ArrayList<>(); 46 | try { 47 | JsonArray jsonArray = sJsonParser.parse(jsonData).getAsJsonArray(); 48 | for (JsonElement element : jsonArray) { 49 | entities.add(sGson.fromJson(element, entityClass)); 50 | } 51 | } catch (JsonSyntaxException e) { 52 | e.printStackTrace(); 53 | } 54 | return entities; 55 | } 56 | 57 | /** 58 | * 将 Object 对象转为 String 59 | * @param jsonData json对象 60 | * @return json字符串 61 | */ 62 | public static String object2JsonStr(Object jsonData) { 63 | return sGson.toJson(jsonData); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/shape_edit_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/v2_sel_btn_send.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/v2_sel_btn_send_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/v2_shape_comment_border.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_custom_danmaku.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 17 | 18 | 22 | 23 | 30 | 31 | 38 | 39 | 57 | 58 |