├── .gitignore
├── .idea
├── codeStyles
│ └── Project.xml
├── libraries
│ ├── Dart_SDK.xml
│ └── Flutter_for_Android.xml
├── modules.xml
├── runConfigurations
│ └── example_lib_main_dart.xml
└── workspace.xml
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── android
├── .gitignore
├── .idea
│ ├── caches
│ │ └── build_file_checksums.ser
│ ├── codeStyles
│ │ └── Project.xml
│ ├── gradle.xml
│ ├── misc.xml
│ ├── modules.xml
│ └── runConfigurations.xml
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── libs
│ ├── arm64-v8a
│ │ ├── libijkffmpeg.so
│ │ ├── libijkplayer.so
│ │ └── libijksdl.so
│ ├── armeabi-v7a
│ │ ├── libijkffmpeg.so
│ │ ├── libijkplayer.so
│ │ └── libijksdl.so
│ └── flutter.jar
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── cn
│ │ └── ugle
│ │ └── plugin
│ │ └── ijkplayer
│ │ ├── IJKPlayerController.java
│ │ ├── IJKPlayerFactory.java
│ │ ├── IJKPlayerListener.java
│ │ ├── IJKPlayerPlugin.java
│ │ └── IJKPlayerView.java
│ └── jniLibs
│ ├── arm64-v8a
│ ├── libijkffmpeg.so
│ ├── libijkplayer.so
│ └── libijksdl.so
│ └── armeabi-v7a
│ ├── libijkffmpeg.so
│ ├── libijkplayer.so
│ └── libijksdl.so
├── example
├── .gitignore
├── .metadata
├── README.md
├── android
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── cn
│ │ │ │ └── ugle
│ │ │ │ └── plugin
│ │ │ │ └── ijkplayerexample
│ │ │ │ └── MainActivity.java
│ │ │ └── res
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ └── values
│ │ │ └── styles.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ └── settings.gradle
├── ios
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Podfile
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── WorkspaceSettings.xcsettings
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── WorkspaceSettings.xcsettings
│ └── Runner
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ └── README.md
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── main.m
├── lib
│ └── main.dart
├── pubspec.yaml
└── test
│ └── widget_test.dart
├── ijkplayer.iml
├── ios
├── .gitignore
├── Assets
│ └── .gitkeep
├── Classes
│ ├── IJKPlayerController.h
│ ├── IJKPlayerController.m
│ ├── IJKPlayerFactory.h
│ ├── IJKPlayerFactory.m
│ ├── IJKPlayerPlugin.h
│ └── IJKPlayerPlugin.m
├── IJKMediaFramework.framework
│ ├── Headers
│ │ ├── IJKAVMoviePlayerController.h
│ │ ├── IJKFFMonitor.h
│ │ ├── IJKFFMoviePlayerController.h
│ │ ├── IJKFFOptions.h
│ │ ├── IJKKVOController.h
│ │ ├── IJKMPMoviePlayerController.h
│ │ ├── IJKMediaFramework.h
│ │ ├── IJKMediaModule.h
│ │ ├── IJKMediaPlayback.h
│ │ ├── IJKMediaPlayer.h
│ │ ├── IJKNotificationManager.h
│ │ └── IJKSDLGLViewProtocol.h
│ ├── IJKMediaFramework
│ ├── Info.plist
│ └── Modules
│ │ └── module.modulemap
└── ijkplayer.podspec
├── lib
├── flutter_ijkplayer.dart
└── src
│ ├── callbacks.dart
│ ├── ijkplayer.dart
│ ├── ijkplayer_controller.dart
│ ├── ijkplayer_controls.dart
│ ├── ijkplayer_controls_footer.dart
│ ├── ijkplayer_controls_header.dart
│ ├── ijkplayer_controls_with.dart
│ ├── ijkplayer_lifecycle.dart
│ ├── ijkplayer_options.dart
│ ├── ijkplayer_progress_bar.dart
│ ├── ijkplayer_progress_color.dart
│ ├── ijkplayer_state.dart
│ └── ijkplayer_value.dart
├── pubspec.yaml
└── snapshot
├── 1545422510.png
├── IMG_0260.JPG
├── IMG_0261.JPG
├── IMG_0262.JPG
├── IMG_0263.JPG
├── IMG_0264.JPG
├── IMG_0265.JPG
├── IMG_0266.JPG
├── IMG_0267.JPG
├── QQ图片20190322205804.jpg
├── QQ图片20190322205813.jpg
└── QQ截图20190216150720.png
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .dart_tool/
3 |
4 | .packages
5 | .pub/
6 | pubspec.lock
7 |
8 | build/
9 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.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 |
--------------------------------------------------------------------------------
/.idea/libraries/Dart_SDK.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/libraries/Flutter_for_Android.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/example_lib_main_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.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 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 | 1543642053386
115 |
116 |
117 | 1543642053386
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: a2a1311a1a3e8f4f0a204ed7ce47ddd82706b60a
8 | channel: master
9 |
10 | project_type: plugin
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 0.0.1
2 |
3 | * TODO: Describe initial release.
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 uking
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Flutter_IJKPlayer Plugin
2 |
3 | ## 1.Build On AndroidView And UIKitView
4 | 这个Flutter IJKPlayer 插件是基于platformview开发的,
5 | 实现了一大部分功能,还有一些功能没去做,开发者可以自行下载修改
6 | 增加其他功能。由于性能上有问题,还有一些其他问题,中途就放弃了。
7 | 改用Texture实现了另一个ijkplayer版本,现在基本完成了,也摆脱
8 | 了用flatformview实现过程中遇到的问题。
9 |
10 | 注:此版需要有开发者能力的人自行修改,
11 | 如果你没有原生开发能请别去折腾了,此版我看到好些新手会遇到一些问题,如果你有开发与熟悉集成flutter插件这些都不是问题
12 | 基于纹理的版本请扫下面APK二维码测试
13 |
14 | 有技术问题可联系我qq:189316826
15 |
16 | ### IJKPlayer Options
17 |
18 | ijplayer options及点播、直播优化设置请自己百度
19 |
20 |
21 | ## 2.Build On Texture Component
22 |
23 |
24 | ### Android APK
25 | ```
26 | scan the qrcode, download and test Flutter_IJKPlayer on Android
27 | ```
28 |
29 |
30 | ### 抖音效果
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | ### Snapshots on IOS
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 |
--------------------------------------------------------------------------------
/android/.idea/caches/build_file_checksums.ser:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/android/.idea/caches/build_file_checksums.ser
--------------------------------------------------------------------------------
/android/.idea/codeStyles/Project.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 |
--------------------------------------------------------------------------------
/android/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/android/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/android/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | group 'cn.ugle.plugin.ijkplayer'
2 | version '1.0-SNAPSHOT'
3 |
4 | buildscript {
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 |
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:3.2.1'
12 | }
13 | }
14 |
15 | rootProject.allprojects {
16 | repositories {
17 | google()
18 | jcenter()
19 | }
20 | }
21 |
22 | apply plugin: 'com.android.library'
23 |
24 | android {
25 | compileSdkVersion 27
26 |
27 | defaultConfig {
28 | minSdkVersion 16
29 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
30 | ndk {
31 | abiFilters "arm64-v8a", "armeabi-v7a"
32 | }
33 |
34 | }
35 | lintOptions {
36 | disable 'InvalidPackage'
37 | }
38 | sourceSets {
39 | main {
40 | jniLibs.srcDirs = ['src/main/jniLibs']
41 | }
42 | }
43 | }
44 |
45 | dependencies{
46 | implementation 'com.android.support:appcompat-v7:27.1.1'
47 | implementation "tv.danmaku.ijk.media:ijkplayer-java:0.8.8"
48 | implementation "tv.danmaku.ijk.media:ijkplayer-exo:0.8.8"
49 | // implementation files('libs/flutter.jar')
50 | }
51 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=file\:///workplace/android/gradle/gradle-4.10.2-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/android/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 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
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 Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/android/libs/arm64-v8a/libijkffmpeg.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/android/libs/arm64-v8a/libijkffmpeg.so
--------------------------------------------------------------------------------
/android/libs/arm64-v8a/libijkplayer.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/android/libs/arm64-v8a/libijkplayer.so
--------------------------------------------------------------------------------
/android/libs/arm64-v8a/libijksdl.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/android/libs/arm64-v8a/libijksdl.so
--------------------------------------------------------------------------------
/android/libs/armeabi-v7a/libijkffmpeg.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/android/libs/armeabi-v7a/libijkffmpeg.so
--------------------------------------------------------------------------------
/android/libs/armeabi-v7a/libijkplayer.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/android/libs/armeabi-v7a/libijkplayer.so
--------------------------------------------------------------------------------
/android/libs/armeabi-v7a/libijksdl.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/android/libs/armeabi-v7a/libijksdl.so
--------------------------------------------------------------------------------
/android/libs/flutter.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/android/libs/flutter.jar
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/android/src/main/java/cn/ugle/plugin/ijkplayer/IJKPlayerController.java:
--------------------------------------------------------------------------------
1 | package cn.ugle.plugin.ijkplayer;
2 |
3 | import android.content.Context;
4 | import android.util.Log;
5 | import android.view.SurfaceView;
6 | import android.view.View;
7 |
8 |
9 | import java.util.HashMap;
10 | import java.util.LinkedHashMap;
11 | import java.util.List;
12 | import java.util.Map;
13 |
14 | import io.flutter.plugin.common.BinaryMessenger;
15 | import io.flutter.plugin.common.MethodCall;
16 | import io.flutter.plugin.common.MethodChannel;
17 | import io.flutter.plugin.platform.PlatformView;
18 |
19 | import tv.danmaku.ijk.media.player.IMediaPlayer;
20 | import tv.danmaku.ijk.media.player.IjkMediaPlayer;
21 | import tv.danmaku.ijk.media.player.IjkTimedText;
22 |
23 | public class IJKPlayerController implements PlatformView, MethodChannel.MethodCallHandler {
24 |
25 |
26 | private SurfaceView surfaceView;
27 | private final MethodChannel methodChannel;
28 | private final IJKPlayerView mVideoView;
29 | private String mVideoPath;
30 | private Map mOptions;
31 | private final boolean isAutoPlay;
32 | // private boolean isMute = false;
33 | // private boolean isLive = false;
34 |
35 | private final String TAG="FLUTTER_IJKPLAYER";
36 |
37 | @SuppressWarnings("unchecked")
38 | IJKPlayerController(Context context, BinaryMessenger messenger, int id, Object args) {
39 | Map params = (Map) args;
40 | mVideoPath = (String) params.get("url");
41 | isAutoPlay=(boolean)params.get("auto");
42 | Object obj=params.get("options");
43 | if(obj!=null){
44 | mOptions=(Map)obj;
45 | }
46 | methodChannel = new MethodChannel(messenger, "plugin.ugle.cn/piliplayer/" + id);
47 | methodChannel.setMethodCallHandler(this);
48 | mVideoView = new IJKPlayerView(context,mOptions);
49 | setVideoInit();
50 | }
51 |
52 | @Override
53 | public void onMethodCall(MethodCall call, MethodChannel.Result result) {
54 | if (call.method.equals("player#play")) {
55 | play();
56 | result.success(null);
57 | } else if (call.method.equals("player#pause")) {
58 | pasue();
59 | result.success(null);
60 | } else if (call.method.equals("player#stop")) {
61 | stop();
62 | result.success(null);
63 | } else if (call.method.equals("player#setMute")) {
64 | boolean flag = (boolean) call.argument("flag");
65 | setMute(flag);
66 | result.success(null);
67 | } else if (call.method.equals("player#playNewNRL")) {
68 | //[self dispose];
69 | String url = call.argument("url");
70 | boolean flag = (boolean) call.argument("sameSource");
71 | playNewURL(url);
72 | } else if (call.method.equals("player#getRealData")) {
73 | Map map = new HashMap<>();
74 | map.put("currentTime", mVideoView.getCurrentPosition());
75 | map.put("bitrate",mVideoView.getBitRate());
76 | map.put("downloadSpeed",mVideoView.getTcpSeed());
77 | map.put("fpsOutput",mVideoView.getVideoOutputFramesPerSecond());
78 | map.put("fpsDecode",mVideoView.getVideoDecodeFramesPerSecond());
79 | result.success(map);
80 | } else if (call.method.equals("player#totalDuration")) {
81 | Map map = new HashMap<>();
82 | map.put("totalDuration", mVideoView.getDuration());
83 | result.success(map);
84 | } else if (call.method.equals("player#seekTo")) {
85 | //NSNumber* seekTime=call.arguments[@"time"];
86 | long seekTime = Long.parseLong((String) call.argument("time"));
87 | seekTo(seekTime);
88 | result.success(null);
89 | } else if (call.method.equals("player#setVolume")) {
90 | float volume = (float) call.argument("volume");
91 | setVolume(volume / 3);
92 | result.success(null);
93 | } else if (call.method.equals("player#setLoop")) {
94 | boolean flag = (boolean) call.argument("flag");
95 | mVideoView.setLooping(flag);
96 | result.success(null);
97 | } else if (call.method.equals("player#setPlaySpeed")) {
98 | int speed = (int) call.argument("seed");
99 | setPlaySeed(speed);
100 | result.success(null);
101 | } else {
102 | result.notImplemented();
103 | }
104 | }
105 |
106 | @Override
107 | public View getView() {
108 | return mVideoView;
109 | }
110 |
111 | @Override
112 | public void dispose() {
113 | if (mVideoView != null) {
114 | mVideoView.release();
115 | }
116 | }
117 |
118 | private void setVideoInit() {
119 |
120 | //mVideoView.setSurface(surface);
121 | mVideoView.setListener(new IJKPlayerListener() {
122 | @Override
123 | public void onVideoSizeChanged(IMediaPlayer iMediaPlayer, int width, int height, int mVideoSarNum, int mVideoSarDen) {
124 | Map message = new HashMap<>();
125 | message.put("width", width);
126 | message.put("height", height);
127 | methodChannel.invokeMethod("player#videoSizeChange", message);
128 | }
129 |
130 | @Override
131 | public void onBufferingUpdate(IMediaPlayer iMediaPlayer, int precent) {
132 | Map message = new HashMap<>();
133 | message.put("bufferedPrecent", precent>98?100:precent);
134 | methodChannel.invokeMethod("player#durationBuffered", message);
135 | }
136 |
137 | @Override
138 | public void onCompletion(IMediaPlayer iMediaPlayer) {
139 | Map message = new HashMap<>();
140 | message.put("state", 5);
141 | methodChannel.invokeMethod("player#stateChange", message);
142 | }
143 |
144 | @Override
145 | public boolean onError(IMediaPlayer iMediaPlayer, int errorCode, int i1) {
146 | Map message = new HashMap<>();
147 | message.put("state", errorCode);
148 | methodChannel.invokeMethod("player#error", message);
149 | return false;
150 | }
151 |
152 | @Override
153 | public boolean onInfo(IMediaPlayer iMediaPlayer, int what, int extra) {
154 | Map message = new HashMap<>();
155 | message.put("state", "MEDIA_INFO_BUFFERING_END");
156 | methodChannel.invokeMethod("player#videoInfo", message);
157 | return false;
158 | }
159 |
160 | @Override
161 | public void onPrepared(IMediaPlayer iMediaPlayer) {
162 | Map message = new HashMap<>();
163 | message.put("state", 1);//ready
164 | methodChannel.invokeMethod("player#stateChange", message);
165 | if (isAutoPlay) {
166 | play();
167 | }
168 | }
169 |
170 | @Override
171 | public void onSeekComplete(IMediaPlayer iMediaPlayer) {
172 | Map message = new HashMap<>();
173 | message.put("isCompleted", true);
174 | methodChannel.invokeMethod("player#seekCompleted", message);
175 | }
176 | });
177 | mVideoView.setVideoPath(mVideoPath);
178 | }
179 |
180 | //播放或暂停
181 | private void play() {
182 | mVideoView.start();
183 | Map message = new HashMap<>();
184 | message.put("state", 2);//playing
185 | methodChannel.invokeMethod("player#stateChange", message);
186 | }
187 |
188 | private void pasue() {
189 | if (mVideoView.isPlaying()) {
190 | mVideoView.pause();
191 | Map message = new HashMap<>();
192 | message.put("state", 3);//pause
193 | methodChannel.invokeMethod("player#stateChange", message);
194 | }
195 |
196 | }
197 |
198 | //停止播放
199 | private void stop() {
200 | Map message = new HashMap<>();
201 | message.put("state", 4);//stop
202 | methodChannel.invokeMethod("player#stateChange", message);
203 | mVideoView.stop();
204 |
205 | }
206 |
207 | private void playNewURL(String url) {
208 | stop();
209 | mVideoView.setVideoPath(url);
210 | }
211 |
212 | private void setMute(boolean flag) {
213 | if (flag) {
214 | setVolume(0.0f);
215 | } else {
216 | setVolume(0.8f);
217 | }
218 | }
219 |
220 | private void setVolume(float volume) {
221 | float val = (float) Math.max(0.0, Math.min(1.0, volume));
222 | mVideoView.setVolume(val, val);
223 | }
224 |
225 | private void seekTo(long location) {
226 | mVideoView.seekTo(location);
227 | }
228 |
229 | private void setPlaySeed(float seed){
230 | // mVideoView.setSpeed(seed);
231 | }
232 |
233 | }
234 |
--------------------------------------------------------------------------------
/android/src/main/java/cn/ugle/plugin/ijkplayer/IJKPlayerFactory.java:
--------------------------------------------------------------------------------
1 | package cn.ugle.plugin.ijkplayer;
2 |
3 | import android.content.Context;
4 |
5 | import java.util.Map;
6 |
7 | import io.flutter.plugin.common.BinaryMessenger;
8 | import io.flutter.plugin.common.StandardMessageCodec;
9 | import io.flutter.plugin.platform.PlatformView;
10 | import io.flutter.plugin.platform.PlatformViewFactory;
11 |
12 | public class IJKPlayerFactory extends PlatformViewFactory {
13 | private final BinaryMessenger messenger;
14 | public IJKPlayerFactory(BinaryMessenger messenger){
15 | super(StandardMessageCodec.INSTANCE);
16 | this.messenger = messenger;
17 | }
18 | @SuppressWarnings("unchecked")
19 | @Override
20 | public PlatformView create(Context context, int id, Object args) {
21 | //Map params = (Map) args;
22 | return new IJKPlayerController(context, messenger, id, args);
23 | }
24 | }
--------------------------------------------------------------------------------
/android/src/main/java/cn/ugle/plugin/ijkplayer/IJKPlayerListener.java:
--------------------------------------------------------------------------------
1 | package cn.ugle.plugin.ijkplayer;
2 |
3 | import tv.danmaku.ijk.media.player.IMediaPlayer;
4 |
5 | public abstract class IJKPlayerListener implements IMediaPlayer.OnBufferingUpdateListener
6 | , IMediaPlayer.OnCompletionListener, IMediaPlayer.OnPreparedListener, IMediaPlayer.OnInfoListener
7 | , IMediaPlayer.OnVideoSizeChangedListener, IMediaPlayer.OnErrorListener
8 | , IMediaPlayer.OnSeekCompleteListener {
9 | }
10 |
--------------------------------------------------------------------------------
/android/src/main/java/cn/ugle/plugin/ijkplayer/IJKPlayerPlugin.java:
--------------------------------------------------------------------------------
1 | package cn.ugle.plugin.ijkplayer;
2 |
3 | import io.flutter.plugin.common.MethodCall;
4 | import io.flutter.plugin.common.MethodChannel;
5 | import io.flutter.plugin.common.PluginRegistry;
6 |
7 | /** IjkplayerPlugin */
8 | public class IJKPlayerPlugin {
9 | /** Plugin registration. */
10 | public static void registerWith(PluginRegistry.Registrar registrar) {
11 | registrar.platformViewRegistry().registerViewFactory("plugin.ugle.cn/piliplayer", new IJKPlayerFactory(registrar.messenger()));
12 | }
13 | }
--------------------------------------------------------------------------------
/android/src/main/java/cn/ugle/plugin/ijkplayer/IJKPlayerView.java:
--------------------------------------------------------------------------------
1 | package cn.ugle.plugin.ijkplayer;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.support.annotation.AttrRes;
6 | import android.support.annotation.NonNull;
7 | import android.support.annotation.Nullable;
8 | import android.text.TextUtils;
9 | import android.util.AttributeSet;
10 | import android.util.Log;
11 | import android.view.Gravity;
12 | import android.view.SurfaceHolder;
13 | import android.view.SurfaceView;
14 | import android.view.View;
15 | import android.widget.FrameLayout;
16 |
17 | import java.io.IOException;
18 | import java.lang.reflect.Field;
19 | import java.math.BigInteger;
20 | import java.util.HashMap;
21 | import java.util.Locale;
22 | import java.util.Map;
23 |
24 | import tv.danmaku.ijk.media.player.IMediaPlayer;
25 | import tv.danmaku.ijk.media.player.IjkMediaPlayer;
26 |
27 |
28 | public class IJKPlayerView extends FrameLayout {
29 |
30 | /**
31 | * 由ijkplayer提供,用于播放视频,需要给他传入一个surfaceView
32 | */
33 | private IMediaPlayer mMediaPlayer = null;
34 |
35 | /**
36 | * 视频文件地址
37 | */
38 | private String mPath = "";
39 |
40 | private SurfaceView surfaceView;
41 |
42 | private IJKPlayerListener listener;
43 | private Context mContext;
44 |
45 | private Map mOptons;
46 |
47 | public IJKPlayerView(@NonNull Context context, Map options) {
48 | super(context);
49 |
50 | initVideoView(context,options);
51 | }
52 |
53 | public IJKPlayerView(@NonNull Context context, Map options, @Nullable AttributeSet attrs) {
54 | super(context, attrs);
55 | initVideoView(context,options);
56 | }
57 |
58 | public IJKPlayerView(@NonNull Context context, Map options, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
59 | super(context, attrs, defStyleAttr);
60 | initVideoView(context,options);
61 | }
62 |
63 | private void initVideoView(Context context,Map options) {
64 | mContext = context;
65 | mOptons=options;
66 | //获取焦点,不知道有没有必要~。~
67 | setFocusable(true);
68 | }
69 |
70 | /**
71 | * 设置视频地址。
72 | * 根据是否第一次播放视频,做不同的操作。
73 | *
74 | * @param path the path of the video.
75 | */
76 | public void setVideoPath(String path) {
77 | if (TextUtils.equals("", mPath)) {
78 | //如果是第一次播放视频,那就创建一个新的surfaceView
79 | mPath = path;
80 | createSurfaceView();
81 | } else {
82 | //否则就直接load
83 | mPath = path;
84 | load(surfaceView.getHolder());
85 | }
86 | }
87 |
88 | /**
89 | * 新建一个surfaceview
90 | */
91 | private void createSurfaceView() {
92 | //生成一个新的surface view
93 | surfaceView = new SurfaceView(mContext);
94 | surfaceView.getHolder().addCallback(new LmnSurfaceCallback());
95 | LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT
96 | , LayoutParams.MATCH_PARENT, Gravity.CENTER);
97 | surfaceView.setLayoutParams(layoutParams);
98 | this.addView(surfaceView);
99 |
100 | }
101 |
102 | /**
103 | * surfaceView的监听器
104 | */
105 | private class LmnSurfaceCallback implements SurfaceHolder.Callback {
106 | @Override
107 | public void surfaceCreated(SurfaceHolder holder) {
108 |
109 | }
110 |
111 | @Override
112 | public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
113 | //surfaceview创建成功后,加载视频
114 | load(holder);
115 | }
116 |
117 | @Override
118 | public void surfaceDestroyed(SurfaceHolder holder) {
119 | }
120 | }
121 |
122 | /**
123 | * 加载视频
124 | */
125 | private void load(final SurfaceHolder holder) {
126 | //每次都要重新创建IMediaPlayer
127 | createPlayer();
128 | try {
129 | mMediaPlayer.setDataSource(mPath);
130 | } catch (IOException e) {
131 | e.printStackTrace();
132 | }
133 | //给mediaPlayer设置视图
134 | mMediaPlayer.setDisplay(holder);
135 | mMediaPlayer.prepareAsync();
136 | }
137 |
138 | /**
139 | * 创建一个新的player
140 | */
141 | private void createPlayer() {
142 | if (mMediaPlayer != null) {
143 | mMediaPlayer.stop();
144 | mMediaPlayer.setDisplay(null);
145 | mMediaPlayer.release();
146 | }
147 | IjkMediaPlayer ijkMediaPlayer = new IjkMediaPlayer();
148 | ijkMediaPlayer.native_setLogLevel(IjkMediaPlayer.IJK_LOG_SILENT);
149 |
150 |
151 | if(mOptons!=null){
152 | for (Map.Entry entry : mOptons.entrySet()) {
153 | Map map=(Map)entry.getValue();
154 | for(String key : map.keySet()){
155 | int ca=Integer.parseInt(entry.getKey());
156 | long val=Long.parseLong(map.get(key));
157 | ijkMediaPlayer.setOption(ca,key,val);
158 | }
159 | }
160 | }
161 | //ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start_on_prepared", 0);
162 | mMediaPlayer = ijkMediaPlayer;
163 | if (listener != null) {
164 | mMediaPlayer.setOnPreparedListener(listener);
165 | mMediaPlayer.setOnInfoListener(listener);
166 | mMediaPlayer.setOnSeekCompleteListener(listener);
167 | mMediaPlayer.setOnBufferingUpdateListener(listener);
168 | mMediaPlayer.setOnErrorListener(listener);
169 | mMediaPlayer.setOnCompletionListener(listener);
170 | mMediaPlayer.setOnVideoSizeChangedListener(listener);
171 | }
172 | }
173 |
174 | public void setListener(IJKPlayerListener listener) {
175 | this.listener = listener;
176 | if (mMediaPlayer != null) {
177 | mMediaPlayer.setOnPreparedListener(listener);
178 | }
179 | }
180 |
181 | public void start() {
182 | if (mMediaPlayer != null) {
183 | mMediaPlayer.start();
184 | }
185 | }
186 |
187 | public void release() {
188 | if (mMediaPlayer != null) {
189 | mMediaPlayer.reset();
190 | mMediaPlayer.release();
191 | mMediaPlayer = null;
192 | }
193 | }
194 |
195 | public void pause() {
196 | if (mMediaPlayer != null) {
197 | mMediaPlayer.pause();
198 | }
199 | }
200 |
201 | public void stop() {
202 | if (mMediaPlayer != null) {
203 | mMediaPlayer.stop();
204 | }
205 | }
206 |
207 |
208 | public void reset() {
209 | if (mMediaPlayer != null) {
210 | mMediaPlayer.reset();
211 | }
212 | }
213 |
214 |
215 | public long getDuration() {
216 | if (mMediaPlayer != null) {
217 | return mMediaPlayer.getDuration();
218 | } else {
219 | return 0;
220 | }
221 | }
222 |
223 |
224 | public long getCurrentPosition() {
225 | if (mMediaPlayer != null) {
226 | return mMediaPlayer.getCurrentPosition();
227 | } else {
228 | return 0;
229 | }
230 | }
231 |
232 |
233 | public void seekTo(long l) {
234 | if (mMediaPlayer != null) {
235 | mMediaPlayer.seekTo(l);
236 | }
237 | }
238 |
239 | public void setLooping(boolean flag){
240 | if(mMediaPlayer!=null){
241 | mMediaPlayer.setLooping(flag);
242 | }
243 | }
244 |
245 | public boolean isPlaying(){
246 | if(mMediaPlayer!=null){
247 | return mMediaPlayer.isPlaying();
248 | }else{
249 | return false;
250 | }
251 | }
252 |
253 | public boolean isLooping(){
254 | if(mMediaPlayer!=null){
255 | return mMediaPlayer.isLooping();
256 | }else{
257 | return false;
258 | }
259 | }
260 |
261 | public void setVolume(float left,float right){
262 | if(mMediaPlayer!=null){
263 | mMediaPlayer.setVolume(left,right);
264 | }
265 | }
266 |
267 | public void setPlaySpeed(float speed) {
268 | if(mMediaPlayer!=null) {
269 | ((IjkMediaPlayer) mMediaPlayer).setSpeed(speed);
270 | }
271 | }
272 |
273 | public float getPlaySpeed() {
274 | if(mMediaPlayer!=null) {
275 | return ((IjkMediaPlayer) mMediaPlayer).getSpeed(.0f);
276 | }else{
277 | return .0f;
278 | }
279 | }
280 |
281 | public void setWakeMode(int mode){
282 | if(mMediaPlayer!=null){
283 | mMediaPlayer.setWakeMode(mContext,mode);
284 | }
285 | }
286 | private static String formatedSpeed(long bytes,long elapsed_milli) {
287 | if (elapsed_milli <= 0) {
288 | return "0 B/s";
289 | }
290 |
291 | if (bytes <= 0) {
292 | return "0 B/s";
293 | }
294 |
295 | float bytes_per_sec = ((float)bytes) * 1000.f / elapsed_milli;
296 | if (bytes_per_sec >= 1000 * 1000) {
297 | return String.format(Locale.US, "%.2f MB/s", ((float)bytes_per_sec) / 1000 / 1000);
298 | } else if (bytes_per_sec >= 1000) {
299 | return String.format(Locale.US, "%.1f KB/s", ((float)bytes_per_sec) / 1000);
300 | } else {
301 | return String.format(Locale.US, "%d B/s", (long)bytes_per_sec);
302 | }
303 | }
304 |
305 | public String getTcpSeed(){
306 | if(mMediaPlayer!=null) {
307 |
308 | return formatedSpeed(((IjkMediaPlayer) mMediaPlayer).getTcpSpeed(),1000);
309 | }
310 | return formatedSpeed(0,1000);
311 | }
312 | public String getBitRate(){
313 | if(mMediaPlayer!=null) {
314 | long bitRate=((IjkMediaPlayer) mMediaPlayer).getBitRate();
315 |
316 | return String.format(Locale.US, "%.2f kbs", bitRate/1000f);
317 | }
318 | return String.format(Locale.US, "%.2f kbs", .0f);
319 | // float fpsOutput = mp.getVideoOutputFramesPerSecond();
320 | // float fpsDecode = mp.getVideoDecodeFramesPerSecond();
321 | // setRowValue(R.string.fps, String.format(Locale.US, "%.2f / %.2f", fpsDecode, fpsOutput));
322 | }
323 | public float getVideoOutputFramesPerSecond(){
324 | if(mMediaPlayer!=null){
325 | return ((IjkMediaPlayer) mMediaPlayer).getVideoOutputFramesPerSecond();
326 | }
327 | return .0f;
328 | }
329 |
330 | public float getVideoDecodeFramesPerSecond(){
331 | if(mMediaPlayer!=null){
332 | return ((IjkMediaPlayer) mMediaPlayer).getVideoDecodeFramesPerSecond();
333 | }
334 | return .0f;
335 | }
336 | }
337 |
--------------------------------------------------------------------------------
/android/src/main/jniLibs/arm64-v8a/libijkffmpeg.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/android/src/main/jniLibs/arm64-v8a/libijkffmpeg.so
--------------------------------------------------------------------------------
/android/src/main/jniLibs/arm64-v8a/libijkplayer.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/android/src/main/jniLibs/arm64-v8a/libijkplayer.so
--------------------------------------------------------------------------------
/android/src/main/jniLibs/arm64-v8a/libijksdl.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/android/src/main/jniLibs/arm64-v8a/libijksdl.so
--------------------------------------------------------------------------------
/android/src/main/jniLibs/armeabi-v7a/libijkffmpeg.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/android/src/main/jniLibs/armeabi-v7a/libijkffmpeg.so
--------------------------------------------------------------------------------
/android/src/main/jniLibs/armeabi-v7a/libijkplayer.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/android/src/main/jniLibs/armeabi-v7a/libijkplayer.so
--------------------------------------------------------------------------------
/android/src/main/jniLibs/armeabi-v7a/libijksdl.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/android/src/main/jniLibs/armeabi-v7a/libijksdl.so
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.lock
4 | *.log
5 | *.pyc
6 | *.swp
7 | .DS_Store
8 | .atom/
9 | .buildlog/
10 | .history
11 | .svn/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # Visual Studio Code related
20 | .vscode/
21 |
22 | # Flutter/Dart/Pub related
23 | **/doc/api/
24 | .dart_tool/
25 | .flutter-plugins
26 | .packages
27 | .pub-cache/
28 | .pub/
29 | build/
30 |
31 | # Android related
32 | **/android/**/gradle-wrapper.jar
33 | **/android/.gradle
34 | **/android/captures/
35 | **/android/gradlew
36 | **/android/gradlew.bat
37 | **/android/local.properties
38 | **/android/**/GeneratedPluginRegistrant.java
39 |
40 | # iOS/XCode related
41 | **/ios/**/*.mode1v3
42 | **/ios/**/*.mode2v3
43 | **/ios/**/*.moved-aside
44 | **/ios/**/*.pbxuser
45 | **/ios/**/*.perspectivev3
46 | **/ios/**/*sync/
47 | **/ios/**/.sconsign.dblite
48 | **/ios/**/.tags*
49 | **/ios/**/.vagrant/
50 | **/ios/**/DerivedData/
51 | **/ios/**/Icon?
52 | **/ios/**/Pods/
53 | **/ios/**/.symlinks/
54 | **/ios/**/profile
55 | **/ios/**/xcuserdata
56 | **/ios/.generated/
57 | **/ios/Flutter/App.framework
58 | **/ios/Flutter/Flutter.framework
59 | **/ios/Flutter/Generated.xcconfig
60 | **/ios/Flutter/app.flx
61 | **/ios/Flutter/app.zip
62 | **/ios/Flutter/flutter_assets/
63 | **/ios/ServiceDefinitions.json
64 | **/ios/Runner/GeneratedPluginRegistrant.*
65 |
66 | # Exceptions to above rules.
67 | !**/ios/**/default.mode1v3
68 | !**/ios/**/default.mode2v3
69 | !**/ios/**/default.pbxuser
70 | !**/ios/**/default.perspectivev3
71 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
72 |
--------------------------------------------------------------------------------
/example/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: a2a1311a1a3e8f4f0a204ed7ce47ddd82706b60a
8 | channel: master
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # ijkplayer_example
2 |
3 | Demonstrates how to use the ijkplayer plugin.
4 |
5 | ## Getting Started
6 |
7 | For help getting started with Flutter, view our online
8 | [documentation](https://flutter.io/).
9 |
--------------------------------------------------------------------------------
/example/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
26 |
27 | android {
28 | compileSdkVersion 27
29 |
30 | lintOptions {
31 | disable 'InvalidPackage'
32 | }
33 |
34 | defaultConfig {
35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
36 | applicationId "cn.ugle.plugin.ijkplayerexample"
37 | minSdkVersion 16
38 | targetSdkVersion 27
39 | versionCode flutterVersionCode.toInteger()
40 | versionName flutterVersionName
41 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
42 | ndk {
43 | abiFilters "armeabi-v7a"
44 | }
45 | }
46 |
47 | buildTypes {
48 | release {
49 | // TODO: Add your own signing config for the release build.
50 | // Signing with the debug keys for now, so `flutter run --release` works.
51 | signingConfig signingConfigs.debug
52 | }
53 | }
54 | }
55 |
56 | flutter {
57 | source '../..'
58 | }
59 |
60 | dependencies {
61 | testImplementation 'junit:junit:4.12'
62 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
63 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
64 | }
65 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
9 |
10 |
11 |
16 |
21 |
28 |
32 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/cn/ugle/plugin/ijkplayerexample/MainActivity.java:
--------------------------------------------------------------------------------
1 | package cn.ugle.plugin.ijkplayerexample;
2 |
3 | import android.os.Bundle;
4 | import io.flutter.app.FlutterActivity;
5 | import io.flutter.plugins.GeneratedPluginRegistrant;
6 |
7 | public class MainActivity extends FlutterActivity {
8 | @Override
9 | protected void onCreate(Bundle savedInstanceState) {
10 | super.onCreate(savedInstanceState);
11 | GeneratedPluginRegistrant.registerWith(this);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | jcenter()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:3.2.1'
9 | }
10 | }
11 |
12 | allprojects {
13 | repositories {
14 | google()
15 | jcenter()
16 | }
17 | }
18 |
19 | rootProject.buildDir = '../build'
20 | subprojects {
21 | project.buildDir = "${rootProject.buildDir}/${project.name}"
22 | }
23 | subprojects {
24 | project.evaluationDependsOn(':app')
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=file\:///workplace/android/gradle/gradle-4.10.2-all.zip
7 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/example/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def parse_KV_file(file, separator='=')
14 | file_abs_path = File.expand_path(file)
15 | if !File.exists? file_abs_path
16 | return [];
17 | end
18 | pods_ary = []
19 | skip_line_start_symbols = ["#", "/"]
20 | File.foreach(file_abs_path) { |line|
21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
22 | plugin = line.split(pattern=separator)
23 | if plugin.length == 2
24 | podname = plugin[0].strip()
25 | path = plugin[1].strip()
26 | podpath = File.expand_path("#{path}", file_abs_path)
27 | pods_ary.push({:name => podname, :path => podpath});
28 | else
29 | puts "Invalid plugin specification: #{line}"
30 | end
31 | }
32 | return pods_ary
33 | end
34 |
35 | target 'Runner' do
36 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
37 | # referring to absolute paths on developers' machines.
38 | system('rm -rf .symlinks')
39 | system('mkdir -p .symlinks/plugins')
40 |
41 | # Flutter Pods
42 | generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig')
43 | if generated_xcode_build_settings.empty?
44 | puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first."
45 | end
46 | generated_xcode_build_settings.map { |p|
47 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
48 | symlink = File.join('.symlinks', 'flutter')
49 | File.symlink(File.dirname(p[:path]), symlink)
50 | pod 'Flutter', :path => File.join(symlink, File.basename(p[:path]))
51 | end
52 | }
53 |
54 | # Plugin Pods
55 | plugin_pods = parse_KV_file('../.flutter-plugins')
56 | plugin_pods.map { |p|
57 | symlink = File.join('.symlinks', 'plugins', p[:name])
58 | File.symlink(p[:path], symlink)
59 | pod p[:name], :path => File.join(symlink, 'ios')
60 | }
61 | end
62 |
63 | post_install do |installer|
64 | installer.pods_project.targets.each do |target|
65 | target.build_configurations.each do |config|
66 | config.build_settings['ENABLE_BITCODE'] = 'NO'
67 | end
68 | end
69 | end
70 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildSystemType
6 | Original
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildSystemType
6 | Original
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : FlutterAppDelegate
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/example/ios/Runner/AppDelegate.m:
--------------------------------------------------------------------------------
1 | #include "AppDelegate.h"
2 | #include "GeneratedPluginRegistrant.h"
3 |
4 | @implementation AppDelegate
5 |
6 | - (BOOL)application:(UIApplication *)application
7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
8 | [GeneratedPluginRegistrant registerWithRegistry:self];
9 | // Override point for customization after application launch.
10 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
11 | }
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
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 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/example/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ijkplayer_example
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 | NSAppTransportSecurity
45 |
46 | NSAllowsArbitraryLoads
47 |
48 |
49 | UIBackgroundModes
50 |
51 | fetch
52 | remote-notification
53 |
54 | io.flutter.embedded_views_preview
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/example/ios/Runner/main.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char* argv[]) {
6 | @autoreleasepool {
7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/example/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:ijkplayer/flutter_ijkplayer.dart';
3 | import 'package:after_layout/after_layout.dart';
4 |
5 | void main() => runApp(MyApp());
6 |
7 | class MyApp extends StatelessWidget {
8 | // This widget is the root of your application.
9 | @override
10 | Widget build(BuildContext context) {
11 | return MaterialApp(
12 | title: 'Flutter Demo',
13 | theme: ThemeData(
14 | primarySwatch: Colors.blue,
15 | ),
16 | home: MyHomePage(title: 'Flutter Demo Home Page'),
17 | );
18 | }
19 | }
20 |
21 | class MyHomePage extends StatefulWidget {
22 | MyHomePage({Key key, this.title}) : super(key: key);
23 | final String title;
24 |
25 | @override
26 | _MyHomePageState createState() => _MyHomePageState();
27 | }
28 |
29 | class _MyHomePageState extends State {
30 | int _counter = 0;
31 |
32 | void _incrementCounter() {
33 | setState(() {
34 | _counter++;
35 | });
36 | }
37 |
38 | @override
39 | Widget build(BuildContext context) {
40 | return Scaffold(
41 | appBar: AppBar(
42 | title: Text(widget.title),
43 | ),
44 | body: Center(
45 | child: Column(
46 | mainAxisAlignment: MainAxisAlignment.center,
47 | children: [
48 | Text(
49 | 'You have pushed the button this many times:',
50 | ),
51 | Text(
52 | '$_counter',
53 | style: Theme.of(context).textTheme.display1,
54 | ),
55 | ],
56 | ),
57 | ),
58 | floatingActionButton: FloatingActionButton(
59 | onPressed: () {
60 | Navigator.of(context)
61 | .push(new MaterialPageRoute(builder: (ctx) => VideoPage()));
62 | },
63 | tooltip: 'Increment',
64 | child: Icon(Icons.add),
65 | ),
66 | );
67 | }
68 | }
69 |
70 | class VideoPage extends StatefulWidget {
71 | @override
72 | _VideoPageState createState() => _VideoPageState();
73 | }
74 |
75 | class _VideoPageState extends State with AfterLayoutMixin{
76 | PiliPlayerController _playerController;
77 | bool _flag=false;
78 | @override
79 | void initState() {
80 | // TODO: implement initState
81 |
82 | //print(ss);
83 | super.initState();
84 | }
85 |
86 | @override
87 | void dispose() {
88 | // TODO: implement dispose
89 | _playerController.dispose();
90 | super.dispose();
91 | }
92 | @override
93 | void afterFirstLayout(BuildContext context) {
94 | // TODO: implement afterFirstLayout
95 | setState(() {
96 | _flag=true;
97 | });
98 | }
99 |
100 | void _onPlayerCreated(PiliPlayerController controller) {
101 | _playerController = controller;
102 | //_playerController.setBufferingEnabled(flag)
103 | }
104 |
105 | // public static final int OPT_CATEGORY_FORMAT = 1;
106 | // public static final int OPT_CATEGORY_CODEC = 2;
107 | // public static final int OPT_CATEGORY_SWS = 3;
108 | // public static final int OPT_CATEGORY_PLAYER = 4;
109 | @override
110 | Widget build(BuildContext context) {
111 | return Scaffold(
112 | appBar: AppBar(
113 | title: Text("Video"),
114 | ),
115 | body: Container(
116 | child: Column(
117 | children: [
118 | Container(
119 | width: double.infinity,
120 | height: 250,
121 | color: Color(0xFF000000),
122 | child: PiliPlayer(
123 | url: "http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4",
124 | onPlayerCreated: _onPlayerCreated,
125 | auto: false,
126 | isLive: false,
127 | options: {
128 | "4": {"start-on-prepared": "0","enable-accurate-seek":"1"},
129 | "1": {"analyzemaxduration": "100"},
130 | },
131 | ),
132 | ),
133 | RaisedButton(
134 | onPressed: () {
135 | _playerController.play();
136 | },
137 | child: Center(
138 | child: Text("play"),
139 | ),
140 | )
141 | ],
142 | ),
143 | ),
144 | );
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: ijkplayer_example
2 | description: Demonstrates how to use the ijkplayer plugin.
3 | publish_to: 'none'
4 |
5 | environment:
6 | sdk: ">=2.0.0-dev.68.0 <3.0.0"
7 |
8 | dependencies:
9 | flutter:
10 | sdk: flutter
11 |
12 | # The following adds the Cupertino Icons font to your application.
13 | # Use with the CupertinoIcons class for iOS style icons.
14 | cupertino_icons: ^0.1.2
15 | after_layout:
16 |
17 | dev_dependencies:
18 | flutter_test:
19 | sdk: flutter
20 |
21 | ijkplayer:
22 | path: ../
23 |
24 |
25 | # For information on the generic Dart part of this file, see the
26 | # following page: https://www.dartlang.org/tools/pub/pubspec
27 |
28 | # The following section is specific to Flutter.
29 | flutter:
30 |
31 | # The following line ensures that the Material Icons font is
32 | # included with your application, so that you can use the icons in
33 | # the material Icons class.
34 | uses-material-design: true
35 |
36 | # To add assets to your application, add an assets section, like this:
37 | # assets:
38 | # - images/a_dot_burr.jpeg
39 | # - images/a_dot_ham.jpeg
40 |
41 | # An image asset can refer to one or more resolution-specific "variants", see
42 | # https://flutter.io/assets-and-images/#resolution-aware.
43 |
44 | # For details regarding adding assets from package dependencies, see
45 | # https://flutter.io/assets-and-images/#from-packages
46 |
47 | # To add custom fonts to your application, add a fonts section here,
48 | # in this "flutter" section. Each entry in this list should have a
49 | # "family" key with the font family name, and a "fonts" key with a
50 | # list giving the asset and other descriptors for the font. For
51 | # example:
52 | # fonts:
53 | # - family: Schyler
54 | # fonts:
55 | # - asset: fonts/Schyler-Regular.ttf
56 | # - asset: fonts/Schyler-Italic.ttf
57 | # style: italic
58 | # - family: Trajan Pro
59 | # fonts:
60 | # - asset: fonts/TrajanPro.ttf
61 | # - asset: fonts/TrajanPro_Bold.ttf
62 | # weight: 700
63 | #
64 | # For details regarding fonts from package dependencies,
65 | # see https://flutter.io/custom-fonts/#from-packages
66 |
--------------------------------------------------------------------------------
/example/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility that Flutter provides. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:ijkplayer_example/main.dart';
12 |
13 | void main() {
14 | testWidgets('Verify Platform version', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(MyApp());
17 |
18 | // Verify that platform version is retrieved.
19 | expect(
20 | find.byWidgetPredicate(
21 | (Widget widget) => widget is Text &&
22 | widget.data.startsWith('Running on:'),
23 | ),
24 | findsOneWidget,
25 | );
26 | });
27 | }
28 |
--------------------------------------------------------------------------------
/ijkplayer.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .vagrant/
3 | .sconsign.dblite
4 | .svn/
5 |
6 | .DS_Store
7 | *.swp
8 | profile
9 |
10 | DerivedData/
11 | build/
12 | GeneratedPluginRegistrant.h
13 | GeneratedPluginRegistrant.m
14 |
15 | .generated/
16 |
17 | *.pbxuser
18 | *.mode1v3
19 | *.mode2v3
20 | *.perspectivev3
21 |
22 | !default.pbxuser
23 | !default.mode1v3
24 | !default.mode2v3
25 | !default.perspectivev3
26 |
27 | xcuserdata
28 |
29 | *.moved-aside
30 |
31 | *.pyc
32 | *sync/
33 | Icon?
34 | .tags*
35 |
36 | /Flutter/Generated.xcconfig
37 |
--------------------------------------------------------------------------------
/ios/Assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/ios/Assets/.gitkeep
--------------------------------------------------------------------------------
/ios/Classes/IJKPlayerController.h:
--------------------------------------------------------------------------------
1 | //
2 | // IJKPlayerController.h
3 | // Pods-Runner
4 | //
5 | // Created by uking on 2018/12/2.
6 | //
7 |
8 | #import
9 | #import
10 | #import
11 | #import
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface IJKPlayerController
15 | : NSObject
16 | @property(atomic, retain) id player;
17 | - (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args binaryMessenger:(NSObject*)messenger;
18 | - (int)invoke:(IJKMediaEvent)event attributes:(NSDictionary *)attributes;
19 | - (UIView *)view;
20 | @end
21 |
22 | NS_ASSUME_NONNULL_END
23 |
--------------------------------------------------------------------------------
/ios/Classes/IJKPlayerFactory.h:
--------------------------------------------------------------------------------
1 | //
2 | // IJKPlayerFactory.h
3 | // Pods-Runner
4 | //
5 | // Created by uking on 2018/12/2.
6 | //
7 |
8 | #import
9 | NS_ASSUME_NONNULL_BEGIN
10 |
11 | @interface IJKPlayerFactory : NSObject
12 | - (instancetype)initWithMessenger:(NSObject*)messenger;
13 | //- (instancetype)initWithRegistrar:(NSObject*)registrar;
14 | @end
15 |
16 | NS_ASSUME_NONNULL_END
17 |
--------------------------------------------------------------------------------
/ios/Classes/IJKPlayerFactory.m:
--------------------------------------------------------------------------------
1 | //
2 | // IJKPlayerFactory.m
3 | // Pods-Runner
4 | //
5 | // Created by uking on 2018/12/2.
6 | //
7 |
8 | #import "IJKPlayerFactory.h"
9 | #import "IJKPlayerController.h"
10 | @implementation IJKPlayerFactory {
11 | // NSObject* _registrar;
12 | NSObject* _messenger;
13 | //NSObject * _controller;
14 | }
15 |
16 | - (instancetype)initWithMessenger:(NSObject*)messenger {
17 | self = [super init];
18 | if (self) {
19 | _messenger = messenger;
20 | }
21 | return self;
22 | }
23 | - (NSObject*)createArgsCodec {
24 | return [FlutterStandardMessageCodec sharedInstance];
25 | }
26 |
27 | - (NSObject*)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args {
28 | NSLog(@"viewId:%lld",viewId);
29 | return [[IJKPlayerController alloc] initWithFrame:frame viewIdentifier:viewId arguments:args binaryMessenger:_messenger];
30 | }
31 |
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/ios/Classes/IJKPlayerPlugin.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | @interface IJKPlayerPlugin : NSObject
4 | @end
5 |
--------------------------------------------------------------------------------
/ios/Classes/IJKPlayerPlugin.m:
--------------------------------------------------------------------------------
1 | #import "IJKPlayerPlugin.h"
2 | #import "IJKPlayerFactory.h"
3 | @implementation IJKPlayerPlugin
4 | + (void)registerWithRegistrar:(NSObject*)registrar {
5 | NSLog(@"viewId:1231323");
6 | IJKPlayerFactory* playerFactory = [[IJKPlayerFactory alloc] initWithMessenger:registrar.messenger];
7 | [registrar registerViewFactory:playerFactory withId:@"plugin.ugle.cn/piliplayer"];
8 | //[registrar publish:playerFactory];
9 | }
10 |
11 |
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ios/IJKMediaFramework.framework/Headers/IJKAVMoviePlayerController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * IJKAVMoviePlayerController.h
3 | *
4 | * Copyright (c) 2014 Bilibili
5 | * Copyright (c) 2014 Zhang Rui
6 | *
7 | * This file is part of ijkPlayer.
8 | *
9 | * ijkPlayer is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * ijkPlayer is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with ijkPlayer; if not, write to the Free Software
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 | */
23 |
24 | /*
25 | File: AVPlayerDemoPlaybackViewController.h
26 | Abstract: UIViewController managing a playback view, thumbnail view, and associated playback UI.
27 | Version: 1.3
28 |
29 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
30 | Inc. ("Apple") in consideration of your agreement to the following
31 | terms, and your use, installation, modification or redistribution of
32 | this Apple software constitutes acceptance of these terms. If you do
33 | not agree with these terms, please do not use, install, modify or
34 | redistribute this Apple software.
35 |
36 | In consideration of your agreement to abide by the following terms, and
37 | subject to these terms, Apple grants you a personal, non-exclusive
38 | license, under Apple's copyrights in this original Apple software (the
39 | "Apple Software"), to use, reproduce, modify and redistribute the Apple
40 | Software, with or without modifications, in source and/or binary forms;
41 | provided that if you redistribute the Apple Software in its entirety and
42 | without modifications, you must retain this notice and the following
43 | text and disclaimers in all such redistributions of the Apple Software.
44 | Neither the name, trademarks, service marks or logos of Apple Inc. may
45 | be used to endorse or promote products derived from the Apple Software
46 | without specific prior written permission from Apple. Except as
47 | expressly stated in this notice, no other rights or licenses, express or
48 | implied, are granted by Apple herein, including but not limited to any
49 | patent rights that may be infringed by your derivative works or by other
50 | works in which the Apple Software may be incorporated.
51 |
52 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE
53 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
54 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
55 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
56 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
57 |
58 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
59 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
60 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
61 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
62 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
63 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
64 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
65 | POSSIBILITY OF SUCH DAMAGE.
66 |
67 | Copyright (C) 2014 Apple Inc. All Rights Reserved.
68 |
69 | */
70 |
71 | #import "IJKMediaPlayback.h"
72 |
73 | @interface IJKAVMoviePlayerController : NSObject
74 |
75 | - (id)initWithContentURL:(NSURL *)aUrl;
76 | - (id)initWithContentURLString:(NSString *)aUrl;
77 | + (id)getInstance:(NSString *)aUrl;
78 |
79 | @end
80 |
--------------------------------------------------------------------------------
/ios/IJKMediaFramework.framework/Headers/IJKFFMonitor.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Bilibili
3 | * Copyright (c) 2016 Zhang Rui
4 | *
5 | * This file is part of ijkPlayer.
6 | *
7 | * ijkPlayer is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU Lesser General Public
9 | * License as published by the Free Software Foundation; either
10 | * version 2.1 of the License, or (at your option) any later version.
11 | *
12 | * ijkPlayer is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public
18 | * License along with ijkPlayer; if not, write to the Free Software
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 | */
21 |
22 | #import
23 |
24 | @interface IJKFFMonitor : NSObject
25 |
26 | - (instancetype)init;
27 |
28 | @property(nonatomic) NSDictionary *mediaMeta;
29 | @property(nonatomic) NSDictionary *videoMeta;
30 | @property(nonatomic) NSDictionary *audioMeta;
31 |
32 | @property(nonatomic, readonly) int64_t duration; // milliseconds
33 | @property(nonatomic, readonly) int64_t bitrate; // bit / sec
34 | @property(nonatomic, readonly) float fps; // frame / sec
35 | @property(nonatomic, readonly) int width; // width
36 | @property(nonatomic, readonly) int height; // height
37 | @property(nonatomic, readonly) NSString *vcodec; // video codec
38 | @property(nonatomic, readonly) NSString *acodec; // audio codec
39 | @property(nonatomic, readonly) int sampleRate;
40 | @property(nonatomic, readonly) int64_t channelLayout;
41 |
42 | @property(nonatomic) NSString *vdecoder;
43 |
44 | @property(nonatomic) int tcpError;
45 | @property(nonatomic) NSString *remoteIp;
46 |
47 | @property(nonatomic) int httpError;
48 | @property(nonatomic) NSString *httpUrl;
49 | @property(nonatomic) NSString *httpHost;
50 | @property(nonatomic) int httpCode;
51 | @property(nonatomic) int64_t httpOpenTick;
52 | @property(nonatomic) int64_t httpSeekTick;
53 | @property(nonatomic) int httpOpenCount;
54 | @property(nonatomic) int httpSeekCount;
55 | @property(nonatomic) int64_t lastHttpOpenDuration;
56 | @property(nonatomic) int64_t lastHttpSeekDuration;
57 | @property(nonatomic) int64_t filesize;
58 |
59 | @property(nonatomic) int64_t prepareStartTick;
60 | @property(nonatomic) int64_t prepareDuration;
61 | @property(nonatomic) int64_t firstVideoFrameLatency;
62 | @property(nonatomic) int64_t lastPrerollStartTick;
63 | @property(nonatomic) int64_t lastPrerollDuration;
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/ios/IJKMediaFramework.framework/Headers/IJKFFMoviePlayerController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * IJKFFMoviePlayerController.h
3 | *
4 | * Copyright (c) 2013 Bilibili
5 | * Copyright (c) 2013 Zhang Rui
6 | *
7 | * This file is part of ijkPlayer.
8 | *
9 | * ijkPlayer is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * ijkPlayer is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with ijkPlayer; if not, write to the Free Software
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 | */
23 |
24 | #import "IJKMediaPlayback.h"
25 | #import "IJKFFMonitor.h"
26 | #import "IJKFFOptions.h"
27 | #import "IJKSDLGLViewProtocol.h"
28 |
29 | // media meta
30 | #define k_IJKM_KEY_FORMAT @"format"
31 | #define k_IJKM_KEY_DURATION_US @"duration_us"
32 | #define k_IJKM_KEY_START_US @"start_us"
33 | #define k_IJKM_KEY_BITRATE @"bitrate"
34 |
35 | // stream meta
36 | #define k_IJKM_KEY_TYPE @"type"
37 | #define k_IJKM_VAL_TYPE__VIDEO @"video"
38 | #define k_IJKM_VAL_TYPE__AUDIO @"audio"
39 | #define k_IJKM_VAL_TYPE__UNKNOWN @"unknown"
40 |
41 | #define k_IJKM_KEY_CODEC_NAME @"codec_name"
42 | #define k_IJKM_KEY_CODEC_PROFILE @"codec_profile"
43 | #define k_IJKM_KEY_CODEC_LONG_NAME @"codec_long_name"
44 |
45 | // stream: video
46 | #define k_IJKM_KEY_WIDTH @"width"
47 | #define k_IJKM_KEY_HEIGHT @"height"
48 | #define k_IJKM_KEY_FPS_NUM @"fps_num"
49 | #define k_IJKM_KEY_FPS_DEN @"fps_den"
50 | #define k_IJKM_KEY_TBR_NUM @"tbr_num"
51 | #define k_IJKM_KEY_TBR_DEN @"tbr_den"
52 | #define k_IJKM_KEY_SAR_NUM @"sar_num"
53 | #define k_IJKM_KEY_SAR_DEN @"sar_den"
54 | // stream: audio
55 | #define k_IJKM_KEY_SAMPLE_RATE @"sample_rate"
56 | #define k_IJKM_KEY_CHANNEL_LAYOUT @"channel_layout"
57 |
58 | #define kk_IJKM_KEY_STREAMS @"streams"
59 |
60 | typedef enum IJKLogLevel {
61 | k_IJK_LOG_UNKNOWN = 0,
62 | k_IJK_LOG_DEFAULT = 1,
63 |
64 | k_IJK_LOG_VERBOSE = 2,
65 | k_IJK_LOG_DEBUG = 3,
66 | k_IJK_LOG_INFO = 4,
67 | k_IJK_LOG_WARN = 5,
68 | k_IJK_LOG_ERROR = 6,
69 | k_IJK_LOG_FATAL = 7,
70 | k_IJK_LOG_SILENT = 8,
71 | } IJKLogLevel;
72 |
73 | @interface IJKFFMoviePlayerController : NSObject
74 |
75 | - (id)initWithContentURL:(NSURL *)aUrl
76 | withOptions:(IJKFFOptions *)options;
77 |
78 | - (id)initWithContentURLString:(NSString *)aUrlString
79 | withOptions:(IJKFFOptions *)options;
80 |
81 | - (id)initWithMoreContent:(NSURL *)aUrl
82 | withOptions:(IJKFFOptions *)options
83 | withGLView:(UIView *)glView;
84 |
85 | - (id)initWithMoreContentString:(NSString *)aUrlString
86 | withOptions:(IJKFFOptions *)options
87 | withGLView:(UIView *)glView;
88 |
89 | - (void)prepareToPlay;
90 | - (void)play;
91 | - (void)pause;
92 | - (void)stop;
93 | - (BOOL)isPlaying;
94 | - (int64_t)trafficStatistic;
95 | - (float)dropFrameRate;
96 |
97 | - (void)setPauseInBackground:(BOOL)pause;
98 | - (BOOL)isVideoToolboxOpen;
99 |
100 | - (void)setHudValue:(NSString *)value forKey:(NSString *)key;
101 |
102 | + (void)setLogReport:(BOOL)preferLogReport;
103 | + (void)setLogLevel:(IJKLogLevel)logLevel;
104 | + (BOOL)checkIfFFmpegVersionMatch:(BOOL)showAlert;
105 | + (BOOL)checkIfPlayerVersionMatch:(BOOL)showAlert
106 | version:(NSString *)version;
107 |
108 | @property(nonatomic, readonly) CGFloat fpsInMeta;
109 | @property(nonatomic, readonly) CGFloat fpsAtOutput;
110 | @property(nonatomic) BOOL shouldShowHudView;
111 |
112 | - (void)setOptionValue:(NSString *)value
113 | forKey:(NSString *)key
114 | ofCategory:(IJKFFOptionCategory)category;
115 |
116 | - (void)setOptionIntValue:(int64_t)value
117 | forKey:(NSString *)key
118 | ofCategory:(IJKFFOptionCategory)category;
119 |
120 |
121 |
122 | - (void)setFormatOptionValue: (NSString *)value forKey:(NSString *)key;
123 | - (void)setCodecOptionValue: (NSString *)value forKey:(NSString *)key;
124 | - (void)setSwsOptionValue: (NSString *)value forKey:(NSString *)key;
125 | - (void)setPlayerOptionValue: (NSString *)value forKey:(NSString *)key;
126 |
127 | - (void)setFormatOptionIntValue: (int64_t)value forKey:(NSString *)key;
128 | - (void)setCodecOptionIntValue: (int64_t)value forKey:(NSString *)key;
129 | - (void)setSwsOptionIntValue: (int64_t)value forKey:(NSString *)key;
130 | - (void)setPlayerOptionIntValue: (int64_t)value forKey:(NSString *)key;
131 |
132 | @property (nonatomic, retain) id segmentOpenDelegate;
133 | @property (nonatomic, retain) id tcpOpenDelegate;
134 | @property (nonatomic, retain) id httpOpenDelegate;
135 | @property (nonatomic, retain) id liveOpenDelegate;
136 |
137 | @property (nonatomic, retain) id nativeInvokeDelegate;
138 |
139 | - (void)didShutdown;
140 |
141 | #pragma mark KVO properties
142 | @property (nonatomic, readonly) IJKFFMonitor *monitor;
143 |
144 | @end
145 |
146 | #define IJK_FF_IO_TYPE_READ (1)
147 | void IJKFFIOStatDebugCallback(const char *url, int type, int bytes);
148 | void IJKFFIOStatRegister(void (*cb)(const char *url, int type, int bytes));
149 |
150 | void IJKFFIOStatCompleteDebugCallback(const char *url,
151 | int64_t read_bytes, int64_t total_size,
152 | int64_t elpased_time, int64_t total_duration);
153 | void IJKFFIOStatCompleteRegister(void (*cb)(const char *url,
154 | int64_t read_bytes, int64_t total_size,
155 | int64_t elpased_time, int64_t total_duration));
156 |
--------------------------------------------------------------------------------
/ios/IJKMediaFramework.framework/Headers/IJKFFOptions.h:
--------------------------------------------------------------------------------
1 | /*
2 | * IJKFFOptions.h
3 | *
4 | * Copyright (c) 2013-2015 Bilibili
5 | * Copyright (c) 2013-2015 Zhang Rui
6 | *
7 | * This file is part of ijkPlayer.
8 | *
9 | * ijkPlayer is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * ijkPlayer is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with ijkPlayer; if not, write to the Free Software
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 | */
23 |
24 | #import
25 |
26 | typedef enum IJKFFOptionCategory {
27 | kIJKFFOptionCategoryFormat = 1,
28 | kIJKFFOptionCategoryCodec = 2,
29 | kIJKFFOptionCategorySws = 3,
30 | kIJKFFOptionCategoryPlayer = 4,
31 | kIJKFFOptionCategorySwr = 5,
32 | } IJKFFOptionCategory;
33 |
34 | // for codec option 'skip_loop_filter' and 'skip_frame'
35 | typedef enum IJKAVDiscard {
36 | /* We leave some space between them for extensions (drop some
37 | * keyframes for intra-only or drop just some bidir frames). */
38 | IJK_AVDISCARD_NONE =-16, ///< discard nothing
39 | IJK_AVDISCARD_DEFAULT = 0, ///< discard useless packets like 0 size packets in avi
40 | IJK_AVDISCARD_NONREF = 8, ///< discard all non reference
41 | IJK_AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames
42 | IJK_AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes
43 | IJK_AVDISCARD_ALL = 48, ///< discard all
44 | } IJKAVDiscard;
45 |
46 | struct IjkMediaPlayer;
47 |
48 | @interface IJKFFOptions : NSObject
49 |
50 | +(IJKFFOptions *)optionsByDefault;
51 |
52 | -(void)applyTo:(struct IjkMediaPlayer *)mediaPlayer;
53 |
54 | - (void)setOptionValue:(NSString *)value
55 | forKey:(NSString *)key
56 | ofCategory:(IJKFFOptionCategory)category;
57 |
58 | - (void)setOptionIntValue:(int64_t)value
59 | forKey:(NSString *)key
60 | ofCategory:(IJKFFOptionCategory)category;
61 |
62 |
63 | -(void)setFormatOptionValue: (NSString *)value forKey:(NSString *)key;
64 | -(void)setCodecOptionValue: (NSString *)value forKey:(NSString *)key;
65 | -(void)setSwsOptionValue: (NSString *)value forKey:(NSString *)key;
66 | -(void)setPlayerOptionValue: (NSString *)value forKey:(NSString *)key;
67 |
68 | -(void)setFormatOptionIntValue: (int64_t)value forKey:(NSString *)key;
69 | -(void)setCodecOptionIntValue: (int64_t)value forKey:(NSString *)key;
70 | -(void)setSwsOptionIntValue: (int64_t)value forKey:(NSString *)key;
71 | -(void)setPlayerOptionIntValue: (int64_t)value forKey:(NSString *)key;
72 |
73 | @property(nonatomic) BOOL showHudView;
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/ios/IJKMediaFramework.framework/Headers/IJKKVOController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * IJKKVOController.h
3 | *
4 | * Copyright (c) 2014 Bilibili
5 | * Copyright (c) 2014 Zhang Rui
6 | *
7 | * This file is part of ijkPlayer.
8 | *
9 | * ijkPlayer is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * ijkPlayer is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with ijkPlayer; if not, write to the Free Software
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 | */
23 |
24 | #import
25 |
26 | @interface IJKKVOController : NSObject
27 |
28 | - (id)initWithTarget:(NSObject *)target;
29 |
30 | - (void)safelyAddObserver:(NSObject *)observer
31 | forKeyPath:(NSString *)keyPath
32 | options:(NSKeyValueObservingOptions)options
33 | context:(void *)context;
34 | - (void)safelyRemoveObserver:(NSObject *)observer
35 | forKeyPath:(NSString *)keyPath;
36 |
37 | - (void)safelyRemoveAllObservers;
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/ios/IJKMediaFramework.framework/Headers/IJKMPMoviePlayerController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * IJKMPMoviePlayerController.h
3 | *
4 | * Copyright (c) 2013 Bilibili
5 | * Copyright (c) 2013 Zhang Rui
6 | *
7 | * This file is part of ijkPlayer.
8 | *
9 | * ijkPlayer is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * ijkPlayer is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with ijkPlayer; if not, write to the Free Software
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 | */
23 |
24 | #import "IJKMediaPlayback.h"
25 | #import
26 |
27 | @interface IJKMPMoviePlayerController : MPMoviePlayerController
28 |
29 | - (id)initWithContentURL:(NSURL *)aUrl;
30 | - (id)initWithContentURLString:(NSString *)aUrl;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/ios/IJKMediaFramework.framework/Headers/IJKMediaFramework.h:
--------------------------------------------------------------------------------
1 | /*
2 | * IJKMediaFramework.h
3 | *
4 | * Copyright (c) 2013 Bilibili
5 | * Copyright (c) 2013 Zhang Rui
6 | *
7 | * This file is part of ijkPlayer.
8 | *
9 | * ijkPlayer is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * ijkPlayer is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with ijkPlayer; if not, write to the Free Software
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 | */
23 |
24 | #import
25 |
26 | //! Project version number for IJKMediaFramework.
27 | FOUNDATION_EXPORT double IJKMediaFrameworkVersionNumber;
28 |
29 | //! Project version string for IJKMediaFramework.
30 | FOUNDATION_EXPORT const unsigned char IJKMediaFrameworkVersionString[];
31 |
32 | // In this header, you should import all the public headers of your framework using statements like #import
33 | #import
34 | #import
35 | #import
36 | #import
37 | #import
38 | #import
39 | #import
40 | #import
41 | #import
42 | #import
43 |
44 | // backward compatible for old names
45 | #define IJKMediaPlaybackIsPreparedToPlayDidChangeNotification IJKMPMediaPlaybackIsPreparedToPlayDidChangeNotification
46 | #define IJKMoviePlayerLoadStateDidChangeNotification IJKMPMoviePlayerLoadStateDidChangeNotification
47 | #define IJKMoviePlayerPlaybackDidFinishNotification IJKMPMoviePlayerPlaybackDidFinishNotification
48 | #define IJKMoviePlayerPlaybackDidFinishReasonUserInfoKey IJKMPMoviePlayerPlaybackDidFinishReasonUserInfoKey
49 | #define IJKMoviePlayerPlaybackStateDidChangeNotification IJKMPMoviePlayerPlaybackStateDidChangeNotification
50 | #define IJKMoviePlayerIsAirPlayVideoActiveDidChangeNotification IJKMPMoviePlayerIsAirPlayVideoActiveDidChangeNotification
51 | #define IJKMoviePlayerVideoDecoderOpenNotification IJKMPMoviePlayerVideoDecoderOpenNotification
52 | #define IJKMoviePlayerFirstVideoFrameRenderedNotification IJKMPMoviePlayerFirstVideoFrameRenderedNotification
53 | #define IJKMoviePlayerFirstAudioFrameRenderedNotification IJKMPMoviePlayerFirstAudioFrameRenderedNotification
54 | #define IJKMoviePlayerFirstAudioFrameDecodedNotification IJKMPMoviePlayerFirstAudioFrameDecodedNotification
55 | #define IJKMoviePlayerFirstVideoFrameDecodedNotification IJKMPMoviePlayerFirstVideoFrameDecodedNotification
56 | #define IJKMoviePlayerOpenInputNotification IJKMPMoviePlayerOpenInputNotification
57 | #define IJKMoviePlayerFindStreamInfoNotification IJKMPMoviePlayerFindStreamInfoNotification
58 | #define IJKMoviePlayerComponentOpenNotification IJKMPMoviePlayerComponentOpenNotification
59 |
60 | #define IJKMPMoviePlayerAccurateSeekCompleteNotification IJKMPMoviePlayerAccurateSeekCompleteNotification
61 | #define IJKMoviePlayerSeekAudioStartNotification IJKMPMoviePlayerSeekAudioStartNotification
62 | #define IJKMoviePlayerSeekVideoStartNotification IJKMPMoviePlayerSeekVideoStartNotification
63 |
64 |
--------------------------------------------------------------------------------
/ios/IJKMediaFramework.framework/Headers/IJKMediaModule.h:
--------------------------------------------------------------------------------
1 | /*
2 | * IJKMediaModule.h
3 | *
4 | * Copyright (c) 2013 Bilibili
5 | * Copyright (c) 2013 Zhang Rui
6 | *
7 | * This file is part of ijkPlayer.
8 | *
9 | * ijkPlayer is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * ijkPlayer is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with ijkPlayer; if not, write to the Free Software
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 | */
23 |
24 | #import
25 |
26 | @interface IJKMediaModule : NSObject
27 |
28 | + (IJKMediaModule *)sharedModule;
29 |
30 | @property(atomic, getter=isAppIdleTimerDisabled) BOOL appIdleTimerDisabled;
31 | @property(atomic, getter=isMediaModuleIdleTimerDisabled) BOOL mediaModuleIdleTimerDisabled;
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/ios/IJKMediaFramework.framework/Headers/IJKMediaPlayback.h:
--------------------------------------------------------------------------------
1 | /*
2 | * IJKMediaPlayback.h
3 | *
4 | * Copyright (c) 2013 Bilibili
5 | * Copyright (c) 2013 Zhang Rui
6 | *
7 | * This file is part of ijkPlayer.
8 | *
9 | * ijkPlayer is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * ijkPlayer is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with ijkPlayer; if not, write to the Free Software
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 | */
23 |
24 | #import
25 | #import
26 |
27 | typedef NS_ENUM(NSInteger, IJKMPMovieScalingMode) {
28 | IJKMPMovieScalingModeNone, // No scaling
29 | IJKMPMovieScalingModeAspectFit, // Uniform scale until one dimension fits
30 | IJKMPMovieScalingModeAspectFill, // Uniform scale until the movie fills the visible bounds. One dimension may have clipped contents
31 | IJKMPMovieScalingModeFill // Non-uniform scale. Both render dimensions will exactly match the visible bounds
32 | };
33 |
34 | typedef NS_ENUM(NSInteger, IJKMPMoviePlaybackState) {
35 | IJKMPMoviePlaybackStateStopped,
36 | IJKMPMoviePlaybackStatePlaying,
37 | IJKMPMoviePlaybackStatePaused,
38 | IJKMPMoviePlaybackStateInterrupted,
39 | IJKMPMoviePlaybackStateSeekingForward,
40 | IJKMPMoviePlaybackStateSeekingBackward
41 | };
42 |
43 | typedef NS_OPTIONS(NSUInteger, IJKMPMovieLoadState) {
44 | IJKMPMovieLoadStateUnknown = 0,
45 | IJKMPMovieLoadStatePlayable = 1 << 0,
46 | IJKMPMovieLoadStatePlaythroughOK = 1 << 1, // Playback will be automatically started in this state when shouldAutoplay is YES
47 | IJKMPMovieLoadStateStalled = 1 << 2, // Playback will be automatically paused in this state, if started
48 | };
49 |
50 | typedef NS_ENUM(NSInteger, IJKMPMovieFinishReason) {
51 | IJKMPMovieFinishReasonPlaybackEnded,
52 | IJKMPMovieFinishReasonPlaybackError,
53 | IJKMPMovieFinishReasonUserExited
54 | };
55 |
56 | // -----------------------------------------------------------------------------
57 | // Thumbnails
58 |
59 | typedef NS_ENUM(NSInteger, IJKMPMovieTimeOption) {
60 | IJKMPMovieTimeOptionNearestKeyFrame,
61 | IJKMPMovieTimeOptionExact
62 | };
63 |
64 | @protocol IJKMediaPlayback;
65 |
66 | #pragma mark IJKMediaPlayback
67 |
68 | @protocol IJKMediaPlayback
69 |
70 | - (void)prepareToPlay;
71 | - (void)play;
72 | - (void)pause;
73 | - (void)stop;
74 | - (BOOL)isPlaying;
75 | - (void)shutdown;
76 | - (void)setPauseInBackground:(BOOL)pause;
77 |
78 | @property(nonatomic, readonly) UIView *view;
79 | @property(nonatomic) NSTimeInterval currentPlaybackTime;
80 | @property(nonatomic, readonly) NSTimeInterval duration;
81 | @property(nonatomic, readonly) NSTimeInterval playableDuration;
82 | @property(nonatomic, readonly) NSInteger bufferingProgress;
83 |
84 | @property(nonatomic, readonly) BOOL isPreparedToPlay;
85 | @property(nonatomic, readonly) IJKMPMoviePlaybackState playbackState;
86 | @property(nonatomic, readonly) IJKMPMovieLoadState loadState;
87 | @property(nonatomic, readonly) int isSeekBuffering;
88 | @property(nonatomic, readonly) int isAudioSync;
89 | @property(nonatomic, readonly) int isVideoSync;
90 |
91 | @property(nonatomic, readonly) int64_t numberOfBytesTransferred;
92 |
93 | @property(nonatomic, readonly) CGSize naturalSize;
94 | @property(nonatomic) IJKMPMovieScalingMode scalingMode;
95 | @property(nonatomic) BOOL shouldAutoplay;
96 |
97 | @property (nonatomic) BOOL allowsMediaAirPlay;
98 | @property (nonatomic) BOOL isDanmakuMediaAirPlay;
99 | @property (nonatomic, readonly) BOOL airPlayMediaActive;
100 |
101 | @property (nonatomic) float playbackRate;
102 | @property (nonatomic) float playbackVolume;
103 |
104 | - (UIImage *)thumbnailImageAtCurrentTime;
105 |
106 | #pragma mark Notifications
107 |
108 | #ifdef __cplusplus
109 | #define IJK_EXTERN extern "C" __attribute__((visibility ("default")))
110 | #else
111 | #define IJK_EXTERN extern __attribute__((visibility ("default")))
112 | #endif
113 |
114 | // -----------------------------------------------------------------------------
115 | // MPMediaPlayback.h
116 |
117 | // Posted when the prepared state changes of an object conforming to the MPMediaPlayback protocol changes.
118 | // This supersedes MPMoviePlayerContentPreloadDidFinishNotification.
119 | IJK_EXTERN NSString *const IJKMPMediaPlaybackIsPreparedToPlayDidChangeNotification;
120 |
121 | // -----------------------------------------------------------------------------
122 | // MPMoviePlayerController.h
123 | // Movie Player Notifications
124 |
125 | // Posted when the scaling mode changes.
126 | IJK_EXTERN NSString* const IJKMPMoviePlayerScalingModeDidChangeNotification;
127 |
128 | // Posted when movie playback ends or a user exits playback.
129 | IJK_EXTERN NSString* const IJKMPMoviePlayerPlaybackDidFinishNotification;
130 | IJK_EXTERN NSString* const IJKMPMoviePlayerPlaybackDidFinishReasonUserInfoKey; // NSNumber (IJKMPMovieFinishReason)
131 |
132 | // Posted when the playback state changes, either programatically or by the user.
133 | IJK_EXTERN NSString* const IJKMPMoviePlayerPlaybackStateDidChangeNotification;
134 |
135 | // Posted when the network load state changes.
136 | IJK_EXTERN NSString* const IJKMPMoviePlayerLoadStateDidChangeNotification;
137 |
138 | // Posted when the movie player begins or ends playing video via AirPlay.
139 | IJK_EXTERN NSString* const IJKMPMoviePlayerIsAirPlayVideoActiveDidChangeNotification;
140 |
141 | // -----------------------------------------------------------------------------
142 | // Movie Property Notifications
143 |
144 | // Calling -prepareToPlay on the movie player will begin determining movie properties asynchronously.
145 | // These notifications are posted when the associated movie property becomes available.
146 | IJK_EXTERN NSString* const IJKMPMovieNaturalSizeAvailableNotification;
147 |
148 | // -----------------------------------------------------------------------------
149 | // Extend Notifications
150 |
151 | IJK_EXTERN NSString *const IJKMPMoviePlayerVideoDecoderOpenNotification;
152 | IJK_EXTERN NSString *const IJKMPMoviePlayerFirstVideoFrameRenderedNotification;
153 | IJK_EXTERN NSString *const IJKMPMoviePlayerFirstAudioFrameRenderedNotification;
154 | IJK_EXTERN NSString *const IJKMPMoviePlayerFirstAudioFrameDecodedNotification;
155 | IJK_EXTERN NSString *const IJKMPMoviePlayerFirstVideoFrameDecodedNotification;
156 | IJK_EXTERN NSString *const IJKMPMoviePlayerOpenInputNotification;
157 | IJK_EXTERN NSString *const IJKMPMoviePlayerFindStreamInfoNotification;
158 | IJK_EXTERN NSString *const IJKMPMoviePlayerComponentOpenNotification;
159 |
160 | IJK_EXTERN NSString *const IJKMPMoviePlayerDidSeekCompleteNotification;
161 | IJK_EXTERN NSString *const IJKMPMoviePlayerDidSeekCompleteTargetKey;
162 | IJK_EXTERN NSString *const IJKMPMoviePlayerDidSeekCompleteErrorKey;
163 | IJK_EXTERN NSString *const IJKMPMoviePlayerDidAccurateSeekCompleteCurPos;
164 | IJK_EXTERN NSString *const IJKMPMoviePlayerAccurateSeekCompleteNotification;
165 | IJK_EXTERN NSString *const IJKMPMoviePlayerSeekAudioStartNotification;
166 | IJK_EXTERN NSString *const IJKMPMoviePlayerSeekVideoStartNotification;
167 |
168 | @end
169 |
170 | #pragma mark IJKMediaUrlOpenDelegate
171 |
172 | // Must equal to the defination in ijkavformat/ijkavformat.h
173 | typedef NS_ENUM(NSInteger, IJKMediaEvent) {
174 |
175 | // Notify Events
176 | IJKMediaEvent_WillHttpOpen = 1, // attr: url
177 | IJKMediaEvent_DidHttpOpen = 2, // attr: url, error, http_code
178 | IJKMediaEvent_WillHttpSeek = 3, // attr: url, offset
179 | IJKMediaEvent_DidHttpSeek = 4, // attr: url, offset, error, http_code
180 | // Control Message
181 | IJKMediaCtrl_WillTcpOpen = 0x20001, // IJKMediaUrlOpenData: no args
182 | IJKMediaCtrl_DidTcpOpen = 0x20002, // IJKMediaUrlOpenData: error, family, ip, port, fd
183 | IJKMediaCtrl_WillHttpOpen = 0x20003, // IJKMediaUrlOpenData: url, segmentIndex, retryCounter
184 | IJKMediaCtrl_WillLiveOpen = 0x20005, // IJKMediaUrlOpenData: url, retryCounter
185 | IJKMediaCtrl_WillConcatSegmentOpen = 0x20007, // IJKMediaUrlOpenData: url, segmentIndex, retryCounter
186 | };
187 |
188 | #define IJKMediaEventAttrKey_url @"url"
189 | #define IJKMediaEventAttrKey_host @"host"
190 | #define IJKMediaEventAttrKey_error @"error"
191 | #define IJKMediaEventAttrKey_time_of_event @"time_of_event"
192 | #define IJKMediaEventAttrKey_http_code @"http_code"
193 | #define IJKMediaEventAttrKey_offset @"offset"
194 | #define IJKMediaEventAttrKey_file_size @"file_size"
195 |
196 | // event of IJKMediaUrlOpenEvent_xxx
197 | @interface IJKMediaUrlOpenData: NSObject
198 |
199 | - (id)initWithUrl:(NSString *)url
200 | event:(IJKMediaEvent)event
201 | segmentIndex:(int)segmentIndex
202 | retryCounter:(int)retryCounter;
203 |
204 | @property(nonatomic, readonly) IJKMediaEvent event;
205 | @property(nonatomic, readonly) int segmentIndex;
206 | @property(nonatomic, readonly) int retryCounter;
207 |
208 | @property(nonatomic, retain) NSString *url;
209 | @property(nonatomic, assign) int fd;
210 | @property(nonatomic, strong) NSString *msg;
211 | @property(nonatomic) int error; // set a negative value to indicate an error has occured.
212 | @property(nonatomic, getter=isHandled) BOOL handled; // auto set to YES if url changed
213 | @property(nonatomic, getter=isUrlChanged) BOOL urlChanged; // auto set to YES by url changed
214 |
215 | @end
216 |
217 | @protocol IJKMediaUrlOpenDelegate
218 |
219 | - (void)willOpenUrl:(IJKMediaUrlOpenData*) urlOpenData;
220 |
221 | @end
222 |
223 | @protocol IJKMediaNativeInvokeDelegate
224 |
225 | - (int)invoke:(IJKMediaEvent)event attributes:(NSDictionary *)attributes;
226 |
227 | @end
228 |
--------------------------------------------------------------------------------
/ios/IJKMediaFramework.framework/Headers/IJKMediaPlayer.h:
--------------------------------------------------------------------------------
1 | /*
2 | * IJKMediaPlayer.h
3 | *
4 | * Copyright (c) 2013 Bilibili
5 | * Copyright (c) 2013 Zhang Rui
6 | *
7 | * This file is part of ijkPlayer.
8 | *
9 | * ijkPlayer is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * ijkPlayer is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with ijkPlayer; if not, write to the Free Software
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 | */
23 |
24 | #import "IJKMediaPlayback.h"
25 | #import "IJKMPMoviePlayerController.h"
26 |
27 | #import "IJKFFOptions.h"
28 | #import "IJKFFMoviePlayerController.h"
29 |
30 | #import "IJKAVMoviePlayerController.h"
31 |
32 | #import "IJKMediaModule.h"
33 |
--------------------------------------------------------------------------------
/ios/IJKMediaFramework.framework/Headers/IJKNotificationManager.h:
--------------------------------------------------------------------------------
1 | /*
2 | * IJKNotificationManager.h
3 | *
4 | * Copyright (c) 2016 Bilibili
5 | * Copyright (c) 2016 Zhang Rui
6 | *
7 | * This file is part of ijkPlayer.
8 | *
9 | * ijkPlayer is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * ijkPlayer is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with ijkPlayer; if not, write to the Free Software
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 | */
23 |
24 | #import
25 |
26 | @interface IJKNotificationManager : NSObject
27 |
28 | - (nullable instancetype)init;
29 |
30 | - (void)addObserver:(nonnull id)observer
31 | selector:(nonnull SEL)aSelector
32 | name:(nullable NSString *)aName
33 | object:(nullable id)anObject;
34 |
35 | - (void)removeAllObservers:(nonnull id)observer;
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/ios/IJKMediaFramework.framework/Headers/IJKSDLGLViewProtocol.h:
--------------------------------------------------------------------------------
1 | /*
2 | * IJKSDLGLViewProtocol.h
3 | *
4 | * Copyright (c) 2017 Bilibili
5 | * Copyright (c) 2017 raymond
6 | *
7 | * This file is part of ijkPlayer.
8 | *
9 | * ijkPlayer is free software; you can redistribute it and/or
10 | * modify it under the terms of the GNU Lesser General Public
11 | * License as published by the Free Software Foundation; either
12 | * version 2.1 of the License, or (at your option) any later version.
13 | *
14 | * ijkPlayer is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | * Lesser General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU Lesser General Public
20 | * License along with ijkPlayer; if not, write to the Free Software
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 | */
23 |
24 | #ifndef IJKSDLGLViewProtocol_h
25 | #define IJKSDLGLViewProtocol_h
26 |
27 | #import
28 |
29 | typedef struct IJKOverlay IJKOverlay;
30 | struct IJKOverlay {
31 | int w;
32 | int h;
33 | UInt32 format;
34 | int planes;
35 | UInt16 *pitches;
36 | UInt8 **pixels;
37 | int sar_num;
38 | int sar_den;
39 | CVPixelBufferRef pixel_buffer;
40 | };
41 |
42 | @protocol IJKSDLGLViewProtocol
43 | - (UIImage*) snapshot;
44 | @property(nonatomic, readonly) CGFloat fps;
45 | @property(nonatomic) CGFloat scaleFactor;
46 | @property(nonatomic) BOOL isThirdGLView;
47 | - (void) display_pixels: (IJKOverlay *) overlay;
48 | @end
49 |
50 | #endif /* IJKSDLGLViewProtocol_h */
51 |
--------------------------------------------------------------------------------
/ios/IJKMediaFramework.framework/IJKMediaFramework:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/ios/IJKMediaFramework.framework/IJKMediaFramework
--------------------------------------------------------------------------------
/ios/IJKMediaFramework.framework/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/ios/IJKMediaFramework.framework/Info.plist
--------------------------------------------------------------------------------
/ios/IJKMediaFramework.framework/Modules/module.modulemap:
--------------------------------------------------------------------------------
1 | framework module IJKMediaFramework {
2 | umbrella header "IJKMediaFramework.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/ios/ijkplayer.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
3 | #
4 | Pod::Spec.new do |s|
5 | s.name = 'ijkplayer'
6 | s.version = '0.0.1'
7 | s.summary = 'A new flutter plugin project.'
8 | s.description = <<-DESC
9 | A new flutter plugin project.
10 | DESC
11 | s.homepage = 'http://example.com'
12 | s.license = { :file => '../LICENSE' }
13 | s.author = { 'uking' => 'ptvile@qq.com' }
14 | s.source = { :path => '.' }
15 | s.source_files = 'Classes/**/*'
16 | s.public_header_files = 'Classes/**/*.h'
17 | s.dependency 'Flutter'
18 | s.vendored_frameworks = "IJKMediaFramework.framework"
19 | s.frameworks = "AudioToolbox", "AVFoundation", "CoreGraphics", "CoreMedia", "CoreVideo", "MobileCoreServices", "OpenGLES", "QuartzCore", "VideoToolbox", "Foundation", "UIKit", "MediaPlayer"
20 | s.libraries = "bz2", "z", "stdc++"
21 | s.requires_arc = true
22 | s.ios.deployment_target = '8.0'
23 | end
24 |
25 |
--------------------------------------------------------------------------------
/lib/flutter_ijkplayer.dart:
--------------------------------------------------------------------------------
1 | library flutter_ijkplayer;
2 |
3 | import 'dart:async';
4 |
5 | import 'package:flutter/foundation.dart';
6 | import 'package:flutter/gestures.dart';
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter/widgets.dart';
9 | import 'package:flutter/services.dart';
10 | export 'dart:async';
11 |
12 |
13 | part 'src/ijkplayer.dart';
14 | part 'src/ijkplayer_options.dart';
15 | part 'src/ijkplayer_controller.dart';
16 | part 'src/ijkplayer_lifecycle.dart';
17 | part 'src/ijkplayer_state.dart';
18 | part 'src/ijkplayer_progress_color.dart';
19 | part 'src/ijkplayer_progress_bar.dart';
20 | part 'src/ijkplayer_value.dart';
21 | part 'src/ijkplayer_controls.dart';
22 | part 'src/ijkplayer_controls_header.dart';
23 | part 'src/ijkplayer_controls_footer.dart';
24 | //part 'src/pili_player_controls_with.dart';
25 | part 'src/callbacks.dart';
--------------------------------------------------------------------------------
/lib/src/callbacks.dart:
--------------------------------------------------------------------------------
1 | part of flutter_ijkplayer;
2 |
3 | /// Callback function taking a single argument.
4 | typedef void ArgumentCallback(T argument);
5 |
6 | /// Mutable collection of [ArgumentCallback] instances, itself an [ArgumentCallback].
7 | ///
8 | /// Additions and removals happening during a single [call] invocation do not
9 | /// change who gets a callback until the next such invocation.
10 | ///
11 | /// Optimized for the singleton case.
12 | class ArgumentCallbacks {
13 | final List> _callbacks = >[];
14 |
15 | /// Callback method. Invokes the corresponding method on each callback
16 | /// in this collection.
17 | ///
18 | /// The list of callbacks being invoked is computed at the start of the
19 | /// method and is unaffected by any changes subsequently made to this
20 | /// collection.
21 | void call(T argument) {
22 | final int length = _callbacks.length;
23 | if (length == 1) {
24 | _callbacks[0].call(argument);
25 | } else if (0 < length) {
26 | for (ArgumentCallback callback
27 | in List>.from(_callbacks)) {
28 | callback(argument);
29 | }
30 | }
31 | }
32 |
33 | /// Adds a callback to this collection.
34 | void add(ArgumentCallback callback) {
35 | assert(callback != null);
36 | _callbacks.add(callback);
37 | }
38 |
39 | /// Removes a callback from this collection.
40 | ///
41 | /// Does nothing, if the callback was not present.
42 | void remove(ArgumentCallback callback) {
43 | _callbacks.remove(callback);
44 | }
45 |
46 | /// Whether this collection is empty.
47 | bool get isEmpty => _callbacks.isEmpty;
48 |
49 | /// Whether this collection is non-empty.
50 | bool get isNotEmpty => _callbacks.isNotEmpty;
51 | }
--------------------------------------------------------------------------------
/lib/src/ijkplayer.dart:
--------------------------------------------------------------------------------
1 | part of flutter_ijkplayer;
2 |
3 | typedef void PiliPlayerCallback(PiliPlayerController controller);
4 |
5 | class PiliPlayer extends StatefulWidget {
6 | PiliPlayer({
7 | Key key,
8 | @required this.url,
9 | //@required this.controller,
10 | @required this.onPlayerCreated,
11 | this.options,
12 | this.auto=false,
13 | this.isLive=false,
14 | this.gestureRecognizers,
15 | }) : super(key: key);
16 |
17 | final PiliPlayerCallback onPlayerCreated;
18 | //final PiliPlayerController controller;
19 | final Map options;
20 | final String url;
21 | final bool auto;
22 | final bool isLive;
23 | /// Which gestures should be consumed by the map.
24 | ///
25 | /// It is possible for other gesture recognizers to be competing with the map on pointer
26 | /// events, e.g if the map is inside a [ListView] the [ListView] will want to handle
27 | /// vertical drags. The map will claim gestures that are recognized by any of the
28 | /// recognizers on this list.
29 | ///
30 | /// When this set is empty or null, the map will only handle pointer events for gestures that
31 | /// were not claimed by any other gesture recognizer.
32 | final Set> gestureRecognizers;
33 |
34 | @override
35 | State createState() => _PiliPlayerState();
36 | }
37 |
38 | class _PiliPlayerState extends State {
39 | //final sKey = GlobalKey<_PiliPlayerState>();
40 | PiliPlayerController _playerController;
41 | bool flag = false;
42 |
43 | @override
44 | void initState() {
45 | super.initState();
46 | }
47 |
48 | @override
49 | void didUpdateWidget(Widget oldWidget) {
50 | super.didUpdateWidget(oldWidget);
51 | }
52 | Widget _buildControls(
53 | BuildContext context,
54 | PiliPlayerController controller,
55 | ) {
56 | return new PiliPlayerControl(
57 | controller: controller,
58 | fullScreen: false,
59 | progressColors: PiliPlayerProgressColors(
60 | playedColor: Colors.green,
61 | bufferedColor: Colors.pink
62 | ),
63 | );
64 | }
65 | Widget _buildVideoPlayer(){
66 | if (defaultTargetPlatform == TargetPlatform.android) {
67 | return AndroidView(
68 | viewType: "plugin.ugle.cn/piliplayer",
69 | onPlatformViewCreated: onPlatformViewCreated,
70 | gestureRecognizers: widget.gestureRecognizers,
71 | creationParams: {"url":widget.url,"options":widget.options,"auto":widget.auto},
72 | creationParamsCodec: const StandardMessageCodec(),
73 | );
74 | } else if (defaultTargetPlatform == TargetPlatform.iOS) {
75 | return UiKitView(
76 | viewType: "plugin.ugle.cn/piliplayer",
77 | onPlatformViewCreated: onPlatformViewCreated,
78 | gestureRecognizers: widget.gestureRecognizers,
79 | creationParams: {"url":widget.url,"options":widget.options,"auto":widget.auto},
80 | creationParamsCodec: const StandardMessageCodec(),
81 | );
82 | }
83 | }
84 | @override
85 | Widget build(BuildContext context) {
86 |
87 | return new Container(
88 | child: new Stack(
89 | children: [
90 | new Center(
91 | child: AspectRatio(
92 | aspectRatio: 1.75,
93 | child:_buildVideoPlayer(),
94 | ),
95 | ),
96 | _playerController!=null?
97 | _buildControls(context, _playerController):Container()
98 | ],
99 | ),
100 | );
101 | }
102 |
103 | Future onPlatformViewCreated(int id) async {
104 | final PiliPlayerController playerController =
105 | await PiliPlayerController.init(id, widget.url, widget.options,widget.auto,widget.isLive);
106 | _playerController=playerController;
107 | widget.onPlayerCreated(playerController);
108 | setState(() {});
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/lib/src/ijkplayer_controller.dart:
--------------------------------------------------------------------------------
1 | part of flutter_ijkplayer;
2 |
3 | typedef void PlayerCallback(dynamic args);
4 | typedef Function PlayerSeekCompletedCallback(bool isCompleted);
5 | enum RotationMode {
6 | PLPlayerNoRotation, // 无旋转
7 | PLPlayerRotateLeft, // 向左旋
8 | PLPlayerRotateRight, // 向右旋
9 | PLPlayerFlipVertical, // 垂直翻转
10 | PLPlayerFlipHorizonal, // 水平翻转
11 | PLPlayerRotate180 // 旋转 180 度
12 | }
13 |
14 | class PiliPlayerController extends ValueNotifier {
15 | PiliPlayerController._(
16 | this._id, this._url, Map options, MethodChannel channel,bool auto,bool live)
17 | : assert(_id != null),
18 | assert(options != null),
19 | assert(_url != null),
20 | assert(channel != null),
21 | _channel = channel,
22 | super(PiliPlayerValue(initialize: false)) {
23 | _channel.setMethodCallHandler(_handleMethodCall);
24 | _options = options;
25 | //autoPlay=options.auto;
26 | isLive=live;
27 | isAuto=auto;
28 | _lifeCycleObserver = _VideoAppLifeCycleObserver(this);
29 | _lifeCycleObserver.initialize();
30 | //value=value.copyWith(isLive: options.isLive,isLooping: options.loop);
31 | }
32 |
33 | static Future init(
34 | id, url, Map options,bool auto,bool live) async {
35 | assert(id != null);
36 | assert(options != null);
37 | assert(url != null);
38 | final MethodChannel channel =
39 | MethodChannel('plugin.ugle.cn/piliplayer/$id');
40 | return PiliPlayerController._(id, url, options, channel,auto,live);
41 | }
42 |
43 | final MethodChannel _channel;
44 | final String _url;
45 | final int _id;
46 | bool isAuto;
47 | bool isLive;
48 | Map get options => _options;
49 | Map _options;
50 | _VideoAppLifeCycleObserver _lifeCycleObserver;
51 | Function _callback;
52 | PlayerSeekCompletedCallback _seekCompletedCallback;
53 | bool get initialize => _initialize;
54 | int get id => _id;
55 | String get url => _url;
56 | bool _initialize = false;
57 | PLPlayerStatus _status = PLPlayerStatus.Unknow;
58 | PLPlayerStatus get playerStatus => _status;
59 | Timer _timer;
60 | int _seekToValue;
61 | // Duration position=Duration(milliseconds: 0);
62 | // Duration duration=Duration(milliseconds: 0);
63 | // Duration durationBuffered=Duration(milliseconds: 0);
64 | // bool hasError=false;
65 | // String errMessage="";
66 | //Stream get playerStateChange =>_eventChannel.receiveBroadcastStream();
67 | // void ss(){
68 | // _eventChannel.receiveBroadcastStream()
69 | // ..listen(eventListener,onError: errorListener);
70 | // }
71 |
72 | void dispose() {
73 | _options = null;
74 | _timer?.cancel();
75 | _lifeCycleObserver?.dispose();
76 | }
77 |
78 | void setSeekCompletedCallback(Function callback) {
79 | if (_seekCompletedCallback != null) {
80 | _seekCompletedCallback = callback;
81 | }
82 | }
83 |
84 | void setStateChangeCallback(Function callback) {
85 | _callback = callback;
86 | }
87 |
88 | PLPlayerStatus _getPlayerState(int state) {
89 | PLPlayerStatus _temp = PLPlayerStatus.values[state];
90 | if (_temp != null) {
91 | return _temp;
92 | }
93 | return PLPlayerStatus.Unknow;
94 | }
95 |
96 | Future _stateChange(int state) async {
97 |
98 | _status = _getPlayerState(state);
99 | if (_initialize) {
100 | value = value.copyWith(isPlaying: _status == PLPlayerStatus.Playing);
101 | }
102 | print(_status);
103 | switch (_status) {
104 | case PLPlayerStatus.Ready:
105 | _initialize = true;
106 | value = value.copyWith(initialize: true,hasError: false);
107 | _getTotalDuration();
108 | if (_lifeCycleObserver.backgroundPaused&&!isLive) {
109 | value=value.copyWith(position: Duration(milliseconds: _lifeCycleObserver.position));
110 | seekTo(_lifeCycleObserver.position);
111 | _lifeCycleObserver.backgroundPaused=false;
112 | _lifeCycleObserver.position=0;
113 | if (_lifeCycleObserver.backgroundStatus == PLPlayerStatus.Playing) {
114 | play();
115 | } else if (_lifeCycleObserver.backgroundStatus ==
116 | PLPlayerStatus.Paused) {
117 | pause();
118 | }
119 | }
120 | //print(duration.inMilliseconds);
121 | break;
122 | case PLPlayerStatus.Playing:
123 | value = value.copyWith(isBuffering: true);
124 | _getPosition();
125 | break;
126 | case PLPlayerStatus.Completed:
127 | value = value.copyWith(position: value.duration); //修复播放结束时间不一至
128 | break;
129 | default:
130 | break;
131 | }
132 | }
133 |
134 | Future _handleMethodCall(MethodCall call) async {
135 | //print(call.method);
136 | switch (call.method) {
137 | case 'player#stateChange':
138 | _stateChange(call.arguments["state"]);
139 | break;
140 | case 'player#error':
141 | //hasError=true;
142 | value = value.copyWith(hasError: true);
143 | //print(call.arguments);
144 | break;
145 | case 'player#seekCompleted':
146 | //print(call.arguments);
147 | if (_status != PLPlayerStatus.Playing && _seekToValue != null) {
148 | value =
149 | value.copyWith(position: Duration(milliseconds: _seekToValue));
150 | _seekToValue = null;
151 | }
152 | break;
153 | case 'player#durationBuffered':
154 | //print(call.arguments);
155 | value =
156 | value.copyWith(bufferedPrecent: call.arguments["bufferedPrecent"]);
157 | break;
158 | case 'player#videoSizeChange':
159 | value = value.copyWith(
160 | size: Size(call.arguments["width"], call.arguments["height"]));
161 | break;
162 | default:
163 | throw MissingPluginException(); //durationBuffered
164 | }
165 | }
166 |
167 | Future _getPosition() async {
168 | if (!_initialize) {
169 | return;
170 | }
171 | if (_status == PLPlayerStatus.Playing) {
172 | _timer = Timer.periodic(
173 | const Duration(milliseconds: 500),
174 | (Timer timer) async {
175 | if (_status != PLPlayerStatus.Playing) {
176 | return;
177 | }
178 | final Map res = await _getRealData();
179 | if (_status != PLPlayerStatus.Playing) {
180 | return;
181 | }
182 | //print(res["currentTime"]);
183 | value = value.copyWith(
184 | position: Duration(milliseconds: int.parse(res["currentTime"])),
185 | // fpsDecode: res["fpsDecode"],
186 | //fpsOutput: res["fpsOutput"],
187 | // downloadSpeed: res["downloadSpeed"],
188 | bitrate: res["bitrate"].toString()
189 | );
190 | },
191 | );
192 | } else {
193 | _timer?.cancel();
194 | //await pause();
195 | }
196 | }
197 |
198 | ///播放
199 | Future play() async {
200 | await _channel.invokeMethod("player#play");
201 | }
202 |
203 | ///暂停
204 | Future pause() async {
205 | await _channel.invokeMethod("player#pause");
206 | }
207 |
208 | ///停止
209 | Future stop() async {
210 | await _channel.invokeMethod("player#stop");
211 | }
212 |
213 | ///播放新的URL
214 | ///
215 | ///@params url
216 | ///
217 | ///@params sameSource 相同的格式的视频 更快播放
218 | Future playNewURL(String url) async {
219 | await _channel
220 | .invokeMethod("player#playNewURL", {"url": url});
221 | }
222 |
223 | ///快速定位到指定播放时间点,
224 | ///
225 | ///该方法仅在回放时起作用,直播场景下该方法直接返回
226 | ///
227 | ///@params time 时间
228 | Future seekTo(int time) async {
229 | _channel.invokeMethod("player#seekTo",
230 | {"time": time}).whenComplete(() {
231 | if (_status != PLPlayerStatus.Playing) {
232 | _seekToValue = time;
233 | }
234 | });
235 | }
236 |
237 | ///是否静音
238 | ///
239 | ///@params flag 时间
240 | Future setMute(bool flag) async {
241 | await _channel
242 | .invokeMethod("player#setMute", {"flag": flag});
243 | }
244 |
245 | ///设置播放画面旋转模式
246 | ///
247 | ///@params mode 旋转模式
248 | // Future setRotationMode(RotationMode mode) async {
249 | // await _channel.invokeMethod(
250 | // "player#setRotationMode", {"mode": mode.index});
251 | // }
252 |
253 | ///设置音亮
254 | ///
255 | ///@params volume 范围0〜3.0 默认为1.0
256 | Future setVolume(double volume) async {
257 | await _channel
258 | .invokeMethod("player#setVolume", {"volume": volume});
259 | }
260 |
261 | ///设置循环播放
262 | ///
263 | ///@params flag
264 | Future setLoop(bool flag) async {
265 | value = value.copyWith(isLooping: flag);
266 | await _channel
267 | .invokeMethod("player#setLoop", {"flag": flag});
268 | }
269 |
270 | ///变速播放
271 | ///
272 | ///@params speed 范围0.2〜32 默认为1.0
273 | Future setPlaySpeed(double speed) async {
274 | await _channel
275 | .invokeMethod("player#setPlaySpeed", {"speed": speed});
276 | }
277 |
278 | ///设置是否缓冲
279 | ///
280 | ///@params flag 为false时会暂停播放 默认为true
281 | // Future setBufferingEnabled(bool flag) async {
282 | // value = value.copyWith(isBuffering: flag);
283 | // await _channel.invokeMethod(
284 | // "player#setBufferingEnabled", {"flag": flag});
285 | // }
286 |
287 | ///获取已缓冲大小(文件大小)
288 | // Future get bufferSize async {
289 | // var result = await _channel.invokeMethod("player#getHttpBufferSize");
290 | // return int.parse(result["bufferSize"]);
291 | // }
292 |
293 | ///获取当前时间
294 | Future> _getRealData() async {
295 | Map result =
296 | await _channel.invokeMethod("player#getRealData");
297 | return result;
298 | }
299 |
300 | ///获取总时间
301 | Future _getTotalDuration() async {
302 | var result = await _channel.invokeMethod("player#totalDuration");
303 | value = value.copyWith(
304 | duration: Duration(milliseconds: int.parse(result["totalDuration"])));
305 | }
306 | }
307 |
--------------------------------------------------------------------------------
/lib/src/ijkplayer_controls.dart:
--------------------------------------------------------------------------------
1 | part of flutter_ijkplayer;
2 |
3 | class MaterialControls extends StatefulWidget {
4 | final PiliPlayerController controller;
5 | final bool fullScreen;
6 | final Future Function() onExpandCollapse;
7 | final PiliPlayerProgressColors progressColors;
8 | final bool autoPlay;
9 | final bool isLive;
10 |
11 | MaterialControls({
12 | @required this.controller,
13 | @required this.fullScreen,
14 | @required this.onExpandCollapse,
15 | @required this.progressColors,
16 | @required this.autoPlay,
17 | @required this.isLive,
18 | });
19 |
20 | @override
21 | State createState() {
22 | return new _MaterialControlsState();
23 | }
24 | }
25 |
26 | class _MaterialControlsState extends State {
27 | PiliPlayerValue _latestValue;
28 | double _latestVolume;
29 | bool _hideStuff = true;
30 | Timer _hideTimer;
31 | Timer _showTimer;
32 | Timer _showAfterExpandCollapseTimer;
33 | bool _dragging = false;
34 |
35 | final barHeight = 35.0;
36 | final marginSize = 5.0;
37 |
38 | @override
39 | Widget build(BuildContext context) {
40 | return new Column(
41 | children: [
42 | _buildBackButton(context),
43 | _latestValue != null &&
44 | !_latestValue.isPlaying &&
45 | _latestValue.duration == null ||
46 | _latestValue.isBuffering
47 | ? Expanded(
48 | child: Center(
49 | child: Container(
50 | width: 20.0,
51 | height: 20.0,
52 | child: const CircularProgressIndicator(
53 | strokeWidth: 2.0,
54 | valueColor:
55 | AlwaysStoppedAnimation(Color(0xFFFF5A5F)),
56 | ),
57 | ),
58 | ),
59 | )
60 | : _buildHitArea(),
61 | _buildBottomBar(context, widget.controller),
62 | //_buildMiniBar(context, widget.controller)
63 | ],
64 | );
65 | }
66 |
67 |
68 | @override
69 | void dispose() {
70 | _dispose();
71 | super.dispose();
72 | }
73 |
74 | void _dispose() {
75 | widget.controller.removeListener(_updateState);
76 | _hideTimer?.cancel();
77 | _showTimer?.cancel();
78 | _showAfterExpandCollapseTimer?.cancel();
79 | }
80 |
81 | @override
82 | void initState() {
83 | _initialize();
84 |
85 | super.initState();
86 | }
87 |
88 | @override
89 | void didUpdateWidget(MaterialControls oldWidget) {
90 | super.didUpdateWidget(oldWidget);
91 | if (widget.controller.url != oldWidget.controller.url) {
92 | _dispose();
93 | _initialize();
94 | }
95 | }
96 |
97 | AnimatedOpacity _buildBottomBar(
98 | BuildContext context,
99 | PiliPlayerController controller,
100 | ) {
101 | final iconColor = Theme.of(context).textTheme.button.color;
102 |
103 | return new AnimatedOpacity(
104 | opacity: _hideStuff ? 0.0 : 1.0,
105 | duration: new Duration(milliseconds: 300),
106 | child: new Container(
107 | height: barHeight,
108 | //color: Theme.of(context).dialogBackgroundColor,
109 | color: Color(0xAAFFFFFF),
110 | child: new Row(
111 | children: [
112 | _buildPlayPause(controller),
113 | widget.isLive
114 | ? Expanded(child: const Text('LIVE'))
115 | : _buildPosition(iconColor),
116 | widget.isLive ? const SizedBox() : _buildProgressBar(),
117 | _buildMuteButton(controller),
118 | _buildExpandButton(),
119 | ],
120 | ),
121 | ),
122 | );
123 | }
124 | Widget _buildBackButton(BuildContext context){
125 | final sWidth=MediaQuery.of(context).size.width;
126 | return Align(
127 | alignment: Alignment.topCenter,
128 | child: Container(
129 | padding: EdgeInsets.symmetric(horizontal: 5.0 ),
130 | width: sWidth,
131 | height: 30.0,
132 | //color: Color(0x99FFFFFF),
133 | child:Row(
134 | children: [
135 | IconButton(
136 | icon: Icon(Icons.keyboard_arrow_left,size: 30.0,color: Color(0xFFFFFFFF),),
137 | onPressed: (){
138 | Navigator.of(context).pop();
139 | },
140 | )
141 |
142 | ],
143 | ) ,
144 | ),
145 | );
146 | }
147 | GestureDetector _buildExpandButton() {
148 | return new GestureDetector(
149 | onTap: _onExpandCollapse,
150 | child: new AnimatedOpacity(
151 | opacity: _hideStuff ? 0.0 : 1.0,
152 | duration: new Duration(milliseconds: 300),
153 | child: new Container(
154 | height: barHeight,
155 | margin: new EdgeInsets.only(right: 12.0),
156 | padding: new EdgeInsets.only(
157 | left: 8.0,
158 | right: 8.0,
159 | ),
160 | child: new Center(
161 | child: new Icon(
162 | widget.fullScreen ? Icons.fullscreen_exit : Icons.fullscreen,
163 | ),
164 | ),
165 | ),
166 | ),
167 | );
168 | }
169 |
170 | Expanded _buildHitArea() {
171 | return new Expanded(
172 | child: new GestureDetector(
173 | onTap: _latestValue != null && _latestValue.isPlaying
174 | ? _cancelAndRestartTimer
175 | : () {
176 | _playPause();
177 |
178 | setState(() {
179 | _hideStuff = true;
180 | });
181 | },
182 | child: new Container(
183 | color: Colors.transparent,
184 | child: new Center(
185 | child: new AnimatedOpacity(
186 | opacity:
187 | _latestValue != null && !_latestValue.isPlaying && !_dragging
188 | ? 1.0
189 | : 0.0,
190 | duration: new Duration(milliseconds: 300),
191 | child: new GestureDetector(
192 | child: new Container(
193 | decoration: new BoxDecoration(
194 | color: Theme.of(context).dialogBackgroundColor,
195 | borderRadius: new BorderRadius.circular(48.0),
196 | ),
197 | child: new Padding(
198 | padding: new EdgeInsets.all(12.0),
199 | child: new Icon(Icons.play_arrow, size: 32.0),
200 | ),
201 | ),
202 | ),
203 | ),
204 | ),
205 | ),
206 | ),
207 | );
208 | }
209 |
210 | GestureDetector _buildMuteButton(
211 | PiliPlayerController controller,
212 | ) {
213 | return new GestureDetector(
214 | onTap: () {
215 | _cancelAndRestartTimer();
216 |
217 | if (_latestValue.volume == 0) {
218 | controller.setVolume(_latestVolume ?? 0.5);
219 | } else {
220 | _latestVolume = controller.value.volume;
221 | controller.setVolume(0.0);
222 | }
223 | },
224 | child: new AnimatedOpacity(
225 | opacity: _hideStuff ? 0.0 : 1.0,
226 | duration: new Duration(milliseconds: 300),
227 | child: new ClipRect(
228 | child: new Container(
229 | child: new Container(
230 | height: barHeight,
231 | padding: new EdgeInsets.only(
232 | left: 8.0,
233 | right: 8.0,
234 | ),
235 | child: new Icon(
236 | (_latestValue != null && _latestValue.volume > 0)
237 | ? Icons.volume_up
238 | : Icons.volume_off,
239 | ),
240 | ),
241 | ),
242 | ),
243 | ),
244 | );
245 | }
246 |
247 | GestureDetector _buildPlayPause(PiliPlayerController controller) {
248 | return new GestureDetector(
249 | onTap: _playPause,
250 | child: new Container(
251 | height: barHeight,
252 | color: Colors.transparent,
253 | margin: new EdgeInsets.only(left: 8.0, right: 4.0),
254 | padding: new EdgeInsets.only(
255 | left: 12.0,
256 | right: 12.0,
257 | ),
258 | child: new Icon(
259 | controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
260 | ),
261 | ),
262 | );
263 | }
264 | String formatDuration(Duration position) {
265 | final ms = position.inMilliseconds;
266 |
267 | int seconds = ms ~/ 1000;
268 | final int hours = seconds ~/ 3600;
269 | seconds = seconds % 3600;
270 | var minutes = seconds ~/ 60;
271 | seconds = seconds % 60;
272 |
273 | final hoursString = hours >= 10 ? '$hours' : hours == 0 ? '00' : '0$hours';
274 |
275 | final minutesString =
276 | minutes >= 10 ? '$minutes' : minutes == 0 ? '00' : '0$minutes';
277 |
278 | final secondsString =
279 | seconds >= 10 ? '$seconds' : seconds == 0 ? '00' : '0$seconds';
280 |
281 | final formattedTime =
282 | '${hoursString == '00' ? '' : hoursString + ':'}$minutesString:$secondsString';
283 |
284 | return formattedTime;
285 | }
286 | Widget _buildPosition(Color iconColor) {
287 | final position = _latestValue != null && _latestValue.position != null
288 | ? _latestValue.position
289 | : Duration.zero;
290 | final duration = _latestValue != null && _latestValue.duration != null
291 | ? _latestValue.duration
292 | : Duration.zero;
293 |
294 | return new Padding(
295 | padding: new EdgeInsets.only(right: 24.0),
296 | child: new Text(
297 | '${formatDuration(position)} / ${formatDuration(duration)}',
298 | style: new TextStyle(
299 | fontSize: 14.0,
300 | ),
301 | ),
302 | );
303 | }
304 |
305 | void _cancelAndRestartTimer() {
306 | _hideTimer?.cancel();
307 | _startHideTimer();
308 |
309 | setState(() {
310 | _hideStuff = false;
311 | });
312 | }
313 |
314 | Future _initialize() async {
315 | widget.controller.addListener(_updateState);
316 |
317 | _updateState();
318 |
319 | if ((widget.controller.value != null &&
320 | widget.controller.value.isPlaying) ||
321 | widget.autoPlay) {
322 | _startHideTimer();
323 | }
324 |
325 | _showTimer = new Timer(new Duration(milliseconds: 200), () {
326 | setState(() {
327 | _hideStuff = false;
328 | });
329 | });
330 | }
331 |
332 | void _onExpandCollapse() {
333 | setState(() {
334 | _hideStuff = true;
335 |
336 | widget.onExpandCollapse().then((dynamic _) {
337 | _showAfterExpandCollapseTimer =
338 | new Timer(new Duration(milliseconds: 300), () {
339 | setState(() {
340 | _cancelAndRestartTimer();
341 | });
342 | });
343 | });
344 | });
345 | }
346 |
347 | void _playPause() {
348 | setState(() {
349 | if (widget.controller.value.isPlaying) {
350 | _hideStuff = false;
351 | _hideTimer?.cancel();
352 | widget.controller.pause();
353 | } else {
354 | _cancelAndRestartTimer();
355 |
356 | if (!widget.controller.value.initialize&&!widget.controller.isAuto) {
357 | widget.controller.play();
358 | } else {
359 | widget.controller.play();
360 | }
361 | }
362 | });
363 | }
364 |
365 | void _startHideTimer() {
366 | _hideTimer = new Timer(const Duration(seconds: 3), () {
367 | setState(() {
368 | _hideStuff = true;
369 | });
370 | });
371 | }
372 |
373 | void _updateState() {
374 | setState(() {
375 | _latestValue = widget.controller.value;
376 | });
377 | }
378 |
379 | Widget _buildProgressBar() {
380 | return new Expanded(
381 | child: new Padding(
382 | padding: new EdgeInsets.only(right: 10.0),
383 | child: new PiliPlayerProgressBar(
384 | widget.controller,
385 | onDragStart: () {
386 | setState(() {
387 | _dragging = true;
388 | });
389 |
390 | _hideTimer?.cancel();
391 | },
392 | onDragEnd: () {
393 | setState(() {
394 | _dragging = false;
395 | });
396 |
397 | _startHideTimer();
398 | },
399 | colors: widget.progressColors ??
400 | new PiliPlayerProgressColors(
401 | playedColor: Theme.of(context).accentColor,
402 | handleColor: Theme.of(context).accentColor,
403 | bufferedColor: Theme.of(context).backgroundColor,
404 | backgroundColor: Theme.of(context).disabledColor),
405 | ),
406 | ),
407 | );
408 | }
409 | }
410 |
--------------------------------------------------------------------------------
/lib/src/ijkplayer_controls_footer.dart:
--------------------------------------------------------------------------------
1 | part of flutter_ijkplayer;
2 |
3 | class PiliPlayerControl extends StatefulWidget {
4 | final PiliPlayerController controller;
5 | final bool fullScreen;
6 | final PiliPlayerProgressColors progressColors;
7 |
8 | PiliPlayerControl({
9 | @required this.controller,
10 | @required this.fullScreen,
11 | @required this.progressColors,
12 | });
13 | @override
14 | _PiliPlayerControlState createState() => _PiliPlayerControlState();
15 | }
16 |
17 | class _PiliPlayerControlState extends State {
18 | PiliPlayerValue _latestValue;
19 | final barHeight = 35.0;
20 | final marginSize = 5.0;
21 | bool _dragging = false;
22 | @override void initState() {
23 | // TODO: implement initStat
24 | _initialize();
25 | super.initState();
26 |
27 | }
28 | @override void dispose(){
29 | widget.controller.removeListener(_updateState);
30 | super.dispose();
31 | }
32 |
33 | Future _initialize() async {
34 | widget.controller.addListener(_updateState);
35 | _updateState();
36 | }
37 |
38 | void _updateState() {
39 | setState(() {
40 | _latestValue = widget.controller.value;
41 | //print(_latestValue);
42 | });
43 | }
44 |
45 | void _playPause() {
46 | if (widget.controller.value.isPlaying) {
47 | widget.controller.pause();
48 | } else {
49 | widget.controller.play();
50 | }
51 | }
52 |
53 | String formatDuration(Duration position) {
54 | final ms = position.inMilliseconds;
55 | int seconds = ms ~/ 1000;
56 | final int hours = seconds ~/ 3600;
57 | seconds = seconds % 3600;
58 | var minutes = seconds ~/ 60;
59 | seconds = seconds % 60;
60 | final hoursString = hours >= 10 ? '$hours' : hours == 0 ? '00' : '0$hours';
61 | final minutesString =
62 | minutes >= 10 ? '$minutes' : minutes == 0 ? '00' : '0$minutes';
63 | final secondsString =
64 | seconds >= 10 ? '$seconds' : seconds == 0 ? '00' : '0$seconds';
65 | final formattedTime =
66 | '${hoursString == '00' ? '' : hoursString + ':'}$minutesString:$secondsString';
67 | return formattedTime;
68 | }
69 |
70 | @override
71 | Widget build(BuildContext context) {
72 | return Container(
73 | height: barHeight,
74 | width: double.infinity,
75 | color: Color(0xFFFF6620),
76 | child: _buildControl(context),
77 | );
78 | }
79 |
80 | Widget _buildControl(BuildContext context) {
81 | return Padding(
82 | padding: EdgeInsets.symmetric(horizontal: 15),
83 | child: Row(
84 | mainAxisAlignment: MainAxisAlignment.center,
85 | children: [
86 | _buildPlayPause(widget.controller),
87 | _buildStartTime(),
88 | _buildProgressBar(),
89 | _buildEndTime(),
90 | _buildFullScreenBtn()
91 | ],
92 | ),
93 | );
94 | }
95 |
96 | GestureDetector _buildPlayPause(PiliPlayerController controller) {
97 | return new GestureDetector(
98 | onTap: _playPause,
99 | child: new Container(
100 | color: Colors.transparent,
101 | margin: new EdgeInsets.only(right: 10.0),
102 | child: new Icon(
103 | controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
104 | ),
105 | ),
106 | );
107 | }
108 |
109 | Widget _buildStartTime() {
110 | final position = _latestValue != null && _latestValue.position != null
111 | ? _latestValue.position
112 | : Duration.zero;
113 | return Padding(
114 | padding: EdgeInsets.only(right: 10.0),
115 | child: Text("${formatDuration(position)}"),
116 | );
117 | }
118 | Widget _buildEndTime() {
119 | final duration = _latestValue != null && _latestValue.position != null
120 | ? _latestValue.duration
121 | : Duration.zero;
122 | return Padding(
123 | padding: EdgeInsets.only(right: 10.0),
124 | child: Text("${formatDuration(duration)}"),
125 | );
126 | }
127 |
128 | Widget _buildProgressBar() {
129 | return new Expanded(
130 | child: new Padding(
131 | padding: new EdgeInsets.only(right: 10.0),
132 | child: new PiliPlayerProgressBar(
133 | widget.controller,
134 | onDragStart: () {
135 | setState(() {
136 | _dragging = true;
137 | });
138 |
139 | //_hideTimer?.cancel();
140 | },
141 | onDragEnd: () {
142 | setState(() {
143 | _dragging = false;
144 | });
145 |
146 | //_startHideTimer();
147 | },
148 | colors: widget.progressColors ??
149 | new PiliPlayerProgressColors(
150 | playedColor: Theme.of(context).accentColor,
151 | handleColor: Theme.of(context).accentColor,
152 | bufferedColor: Theme.of(context).backgroundColor,
153 | backgroundColor: Theme.of(context).disabledColor),
154 | ),
155 | ),
156 | );
157 | }
158 | GestureDetector _buildFullScreenBtn() {
159 | return new GestureDetector(
160 | onTap: _playPause,
161 | child: new Container(
162 | color: Colors.transparent,
163 | child: new Icon(
164 | widget.fullScreen ? Icons.fullscreen_exit : Icons.fullscreen,
165 | ),
166 | ),
167 | );
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/lib/src/ijkplayer_controls_header.dart:
--------------------------------------------------------------------------------
1 | part of flutter_ijkplayer;
2 |
3 | class PiliPlayerControlHeader extends StatefulWidget {
4 | @override
5 | _PiliPlayerControlHeaderState createState() => _PiliPlayerControlHeaderState();
6 | }
7 |
8 | class _PiliPlayerControlHeaderState extends State {
9 | final barHeight = 35.0;
10 | @override
11 | Widget build(BuildContext context) {
12 | return Container(
13 | height: barHeight,
14 | child: Row(
15 | children: [
16 |
17 | ],
18 | ),
19 | );
20 | }
21 | GestureDetector _goBackButton(PiliPlayerController controller) {
22 | return new GestureDetector(
23 | onTap: (){
24 | Navigator.of(context).pop();
25 | },
26 | child: new Container(
27 | color: Colors.transparent,
28 | margin: new EdgeInsets.only(right: 10.0),
29 | child: Icon(Icons.keyboard_arrow_left,color: Color(0xFFFFFFFF),),
30 | ),
31 | );
32 | }
33 | }
--------------------------------------------------------------------------------
/lib/src/ijkplayer_controls_with.dart:
--------------------------------------------------------------------------------
1 | // part of piliplayer;
2 |
3 | // class PlayerWithControls extends StatefulWidget {
4 | // //final PiliPlayerController controller;
5 | // final Future Function() onExpandCollapse;
6 | // final bool fullScreen;
7 | // final PiliPlayerProgressColors cupertinoProgressColors;
8 | // final PiliPlayerProgressColors materialProgressColors;
9 | // final Widget placeholder;
10 | // final double aspectRatio;
11 | // final bool autoPlay;
12 | // final bool showControls;
13 | // final bool isLive;
14 |
15 | // PlayerWithControls({
16 | // Key key,
17 | // //@required this.controller,
18 | // @required this.onExpandCollapse,
19 | // @required this.aspectRatio,
20 | // this.fullScreen = false,
21 | // this.showControls = true,
22 | // this.cupertinoProgressColors,
23 | // this.materialProgressColors,
24 | // this.placeholder,
25 | // this.autoPlay,
26 | // this.isLive = false,
27 | // }) : super(key: key);
28 |
29 | // @override
30 | // State createState() {
31 | // return new _VideoPlayerWithControlsState();
32 | // }
33 | // }
34 |
35 | // class _VideoPlayerWithControlsState extends State {
36 | // @override
37 | // Widget build(BuildContext context) {
38 | // final controller = widget.controller;
39 |
40 | // return new Center(
41 | // child: new Container(
42 | // width: MediaQuery.of(context).size.width,
43 | // child: new AspectRatio(
44 | // aspectRatio: widget.aspectRatio,
45 | // child: _buildPlayerWithControls(controller, context),
46 | // ),
47 | // ),
48 | // );
49 | // }
50 |
51 | // Container _buildPlayerWithControls(
52 | // PiliPlayerController controller, BuildContext context) {
53 | // return new Container(
54 | // child: new Stack(
55 | // children: [
56 | // widget.placeholder ?? new Container(),
57 | // new Center(
58 | // child: new Hero(
59 | // tag: controller,
60 | // child: new AspectRatio(
61 | // aspectRatio: widget.aspectRatio,
62 | // child: new VideoPlayer(controller),
63 | // ),
64 | // ),
65 | // ),
66 | // _buildControls(context, controller),
67 | // ],
68 | // ),
69 | // );
70 | // }
71 |
72 | // Widget _buildControls(
73 | // BuildContext context,
74 | // PiliPlayerController controller,
75 | // ) {
76 | // return widget.showControls
77 | // ?
78 | // new MaterialControls(
79 | // controller: controller,
80 | // onExpandCollapse: widget.onExpandCollapse,
81 | // fullScreen: widget.fullScreen,
82 | // progressColors: widget.materialProgressColors,
83 | // autoPlay: widget.autoPlay,
84 | // isLive: widget.isLive,
85 | // )
86 |
87 | // : new Container();
88 | // }
89 |
90 | // @override
91 | // void initState() {
92 | // // Hack to show the video when it starts playing. Should be fixed by the
93 | // // Plugin IMO.
94 | // widget.controller.addListener(_onPlay);
95 |
96 | // super.initState();
97 | // }
98 |
99 | // @override
100 | // void didUpdateWidget(PlayerWithControls oldWidget) {
101 | // super.didUpdateWidget(oldWidget);
102 |
103 | // if (widget.controller.url != oldWidget.controller.url) {
104 | // widget.controller.addListener(_onPlay);
105 | // }
106 | // }
107 |
108 | // @override
109 | // dispose() {
110 | // widget.controller.removeListener(_onPlay);
111 | // super.dispose();
112 | // }
113 |
114 | // void _onPlay() {
115 | // if (widget.controller.value.isPlaying) {
116 | // setState(() {
117 | // widget.controller.removeListener(_onPlay);
118 | // });
119 | // }
120 | // }
121 | // }
--------------------------------------------------------------------------------
/lib/src/ijkplayer_lifecycle.dart:
--------------------------------------------------------------------------------
1 | part of flutter_ijkplayer;
2 |
3 | class _VideoAppLifeCycleObserver extends Object with WidgetsBindingObserver {
4 | _VideoAppLifeCycleObserver(this._controller);
5 |
6 | bool _wasPlayingBeforePause = false;
7 | final PiliPlayerController _controller;
8 | int position;
9 | bool backgroundPaused = false;
10 | PLPlayerStatus backgroundStatus;
11 | void initialize() {
12 | WidgetsBinding.instance.addObserver(this);
13 | }
14 |
15 | @override
16 | void didChangeAppLifecycleState(AppLifecycleState state) {
17 | switch (state) {
18 | case AppLifecycleState.paused:
19 | if (!_controller.isLive) {//只处理点播情况
20 | backgroundPaused = true;
21 | backgroundStatus = _controller._status;
22 | position = _controller.value.position.inMilliseconds;
23 | }
24 | _wasPlayingBeforePause =
25 | _controller.playerStatus == PLPlayerStatus.Playing;
26 | _controller.pause();
27 | break;
28 | case AppLifecycleState.resumed:
29 | if (_wasPlayingBeforePause) {
30 | _controller.play();
31 | }
32 | break;
33 | default:
34 | }
35 | }
36 |
37 | void dispose() {
38 | WidgetsBinding.instance.removeObserver(this);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/lib/src/ijkplayer_options.dart:
--------------------------------------------------------------------------------
1 | part of flutter_ijkplayer;
2 |
3 | enum IJKOptionType{
4 | OPT_CATEGORY_UNKNOW,
5 | OPT_CATEGORY_FORMAT,
6 | OPT_CATEGORY_CODEC,
7 | OPT_CATEGORY_SWS,
8 | OPT_CATEGORY_PLAYER
9 | }
10 | class IJKPlayerOption{
11 | final Map> kv;
12 | IJKPlayerOption({this.kv});
13 | }
14 | class IJKeyValue{
15 | String key;
16 | int value;
17 | }
--------------------------------------------------------------------------------
/lib/src/ijkplayer_progress_bar.dart:
--------------------------------------------------------------------------------
1 | part of flutter_ijkplayer;
2 |
3 | class PiliPlayerProgressBar extends StatefulWidget {
4 | final PiliPlayerController controller;
5 | final PiliPlayerProgressColors colors;
6 | final Function() onDragStart;
7 | final Function() onDragEnd;
8 | final Function() onDragUpdate;
9 |
10 | PiliPlayerProgressBar(
11 | this.controller, {
12 | PiliPlayerProgressColors colors,
13 | this.onDragEnd,
14 | this.onDragStart,
15 | this.onDragUpdate,
16 | }) : colors = colors ?? new PiliPlayerProgressColors();
17 |
18 | @override
19 | _VideoProgressBarState createState() {
20 | return new _VideoProgressBarState();
21 | }
22 | }
23 |
24 | class _VideoProgressBarState extends State {
25 | VoidCallback listener;
26 |
27 | bool _controllerWasPlaying = false;
28 | Offset _dragOffset;
29 |
30 | _VideoProgressBarState() {
31 | listener = () {
32 | setState(() {});
33 | };
34 | }
35 |
36 | PiliPlayerController get controller => widget.controller;
37 |
38 | @override
39 | void initState() {
40 | super.initState();
41 | controller.addListener(listener);
42 | }
43 |
44 | @override
45 | void deactivate() {
46 | controller.removeListener(listener);
47 | super.deactivate();
48 | }
49 |
50 | @override
51 | Widget build(BuildContext context) {
52 | void seekToRelativePosition(Offset globalPosition) {
53 | final RenderBox box = context.findRenderObject();
54 | final Offset tapPos = box.globalToLocal(globalPosition);
55 | final double relative = tapPos.dx / box.size.width;
56 | final Duration position = controller.value.duration * relative;
57 | print("position.inMilliseconds:"+position.inMilliseconds.toString());
58 | controller.seekTo(position.inMilliseconds);
59 | }
60 |
61 | return new GestureDetector(
62 | child: Center(
63 | child: new Container(
64 | height: MediaQuery.of(context).size.height / 2,
65 | width: MediaQuery.of(context).size.width,
66 | color: Colors.transparent,
67 | child: new CustomPaint(
68 | painter: new _ProgressBarPainter(
69 | controller.value,
70 | widget.colors,
71 | ),
72 | ),
73 | ),
74 | ),
75 | // onHorizontalDragStart: (DragStartDetails details) {
76 | // if (!controller.value.initialize) {
77 | // return;
78 | // }
79 |
80 | // _controllerWasPlaying = controller.value.isPlaying;
81 | // if (_controllerWasPlaying) {
82 | // controller.pause();
83 | // }
84 |
85 | // if (widget.onDragStart != null) {
86 | // widget.onDragStart();
87 | // }
88 | // },
89 | // onHorizontalDragUpdate: (DragUpdateDetails details) {
90 | // if (!controller.value.initialize) {
91 | // return;
92 | // }
93 |
94 | // _dragOffset=details.globalPosition;
95 |
96 | // if (widget.onDragUpdate != null) {
97 | // widget.onDragUpdate();
98 | // }
99 | // },
100 | // onHorizontalDragEnd: (DragEndDetails details) {
101 | // if(_dragOffset!=null){
102 | // seekToRelativePosition(_dragOffset);
103 | // }
104 |
105 | // if (_controllerWasPlaying) {
106 | // controller.play();
107 | // }
108 |
109 | // if (widget.onDragEnd != null) {
110 |
111 | // widget.onDragEnd();
112 | // }
113 | // _dragOffset=null;
114 | // },
115 | onTapDown: (TapDownDetails details) {
116 | if (!controller.value.initialize) {
117 | return;
118 | }
119 | seekToRelativePosition(details.globalPosition);
120 | },
121 | );
122 | }
123 | }
124 |
125 | class _ProgressBarPainter extends CustomPainter {
126 | PiliPlayerValue value;
127 | PiliPlayerProgressColors colors;
128 |
129 | _ProgressBarPainter(this.value, this.colors);
130 |
131 | @override
132 | bool shouldRepaint(CustomPainter painter) {
133 | return true;
134 | }
135 |
136 | @override
137 | void paint(Canvas canvas, Size size) {
138 | final height = 2.0;
139 |
140 | canvas.drawRRect(
141 | new RRect.fromRectAndRadius(
142 | new Rect.fromPoints(
143 | new Offset(0.0, size.height / 2),
144 | new Offset(size.width, size.height / 2 + height),
145 | ),
146 | new Radius.circular(4.0),
147 | ),
148 | colors.backgroundPaint,
149 | );
150 | if (!value.initialize||value.isLive||value.hasError) {
151 | return;
152 | }
153 | final double playedPart = value.position.inMilliseconds /value.duration.inMilliseconds * size.width;
154 | final double bufferdPart = value.bufferedPrecent/100 * size.width;
155 | canvas.drawRRect(
156 | new RRect.fromRectAndRadius(
157 | new Rect.fromPoints(
158 | new Offset(0.0, size.height / 2),
159 | new Offset(bufferdPart, size.height / 2 + height),
160 | ),
161 | new Radius.circular(4.0),
162 | ),
163 | colors.bufferedPaint,
164 | );
165 | canvas.drawRRect(
166 | new RRect.fromRectAndRadius(
167 | new Rect.fromPoints(
168 | new Offset(0.0, size.height / 2),
169 | new Offset(playedPart, size.height / 2 + height),
170 | ),
171 | new Radius.circular(4.0),
172 | ),
173 | colors.playedPaint,
174 | );
175 | canvas.drawCircle(
176 | new Offset(playedPart, size.height / 2 + height / 2),
177 | height * 3,
178 | colors.handlePaint,
179 | );
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/lib/src/ijkplayer_progress_color.dart:
--------------------------------------------------------------------------------
1 | part of flutter_ijkplayer;
2 | class PiliPlayerProgressColors {
3 | final Paint playedPaint;
4 | final Paint bufferedPaint;
5 | final Paint handlePaint;
6 | final Paint backgroundPaint;
7 |
8 | PiliPlayerProgressColors({
9 | Color playedColor: const Color.fromRGBO(255, 0, 0, 0.7),
10 | Color bufferedColor: const Color.fromRGBO(30, 30, 200, 0.2),
11 | Color handleColor: const Color.fromRGBO(200, 200, 200, 1.0),
12 | Color backgroundColor: const Color.fromRGBO(200, 200, 200, 0.5),
13 | }) : playedPaint = new Paint()..color = playedColor,
14 | bufferedPaint = new Paint()..color = bufferedColor,
15 | handlePaint = new Paint()..color = handleColor,
16 | backgroundPaint = new Paint()..color = backgroundColor;
17 | }
--------------------------------------------------------------------------------
/lib/src/ijkplayer_state.dart:
--------------------------------------------------------------------------------
1 | part of flutter_ijkplayer;
2 | /**
3 | PLPlayer 的播放状态
4 |
5 | @since v1.0.0
6 | */
7 | enum PLPlayerStatus{
8 | Unknow,
9 | Ready,
10 | Playing,
11 | Paused,
12 | Stopped,
13 | Completed,
14 | }
--------------------------------------------------------------------------------
/lib/src/ijkplayer_value.dart:
--------------------------------------------------------------------------------
1 | part of flutter_ijkplayer;
2 | class PiliPlayerValue {
3 | PiliPlayerValue({
4 | @required this.initialize,
5 | this.duration=const Duration(milliseconds: 0),
6 | this.position = const Duration(milliseconds: 0),
7 | this.bufferedPrecent = 0,
8 | this.fpsDecode = 0.0,
9 | this.bitrate = '',
10 | this.fpsOutput =0.0,
11 | this.downloadSpeed='',
12 | this.isPlaying = false,
13 | this.isLooping = false,
14 | this.isBuffering = false,
15 | this.isLive = false,
16 | this.volume = 1.0,
17 | this.hasError=false,
18 | this.errMsg,
19 | });
20 |
21 | PiliPlayerValue.uninitialized() : this(initialize: false);
22 |
23 | PiliPlayerValue.erroneous(String errMsg)
24 | : this(initialize: false, errMsg: errMsg);
25 |
26 | /// The total duration of the video.
27 | ///
28 | /// Is null when [initialized] is false.
29 | final Duration duration;
30 |
31 | /// The current playback position.
32 | final Duration position;
33 |
34 | /// The currently buffered precent.
35 | final int bufferedPrecent;
36 |
37 | final String bitrate;
38 | final String downloadSpeed;
39 | final double fpsOutput;
40 | final double fpsDecode;
41 |
42 | /// True if the video is playing. False if it's paused.
43 | final bool isPlaying;
44 |
45 | /// True if the video is looping.
46 | final bool isLooping;
47 |
48 | /// True if the video is currently buffering.
49 | final bool isBuffering;
50 |
51 | final bool isLive;
52 |
53 | final bool initialize;
54 |
55 | /// The current volume of the playback.
56 | final double volume;
57 |
58 | /// A description of the error if present.
59 | ///
60 | /// If [hasError] is false this is [null].
61 | final String errMsg;
62 | //bool get initialized => duration != null;
63 | bool hasError;
64 |
65 | PiliPlayerValue copyWith({
66 | Duration duration,
67 | Size size,
68 | Duration position,
69 | int bufferedPrecent,
70 | String bitrate,
71 | String downloadSpeed,
72 | double fpsOutput,
73 | double fpsDecode,
74 | bool isPlaying,
75 | bool isLooping,
76 | bool isBuffering,
77 | bool isLive,
78 | double volume,
79 | bool initialize,
80 | bool hasError,
81 | String errMsg,
82 | }) {
83 | return PiliPlayerValue(
84 | duration: duration ?? this.duration,
85 | position: position ?? this.position,
86 | bufferedPrecent: bufferedPrecent ?? this.bufferedPrecent,
87 | isPlaying: isPlaying ?? this.isPlaying,
88 | isLooping: isLooping ?? this.isLooping,
89 | isBuffering: isBuffering ?? this.isBuffering,
90 | isLive: isLive ?? this.isLive,
91 | volume: volume ?? this.volume,
92 | errMsg: errMsg ?? this.errMsg,
93 | hasError: hasError ?? this.hasError,
94 | initialize: initialize ?? this.initialize,
95 | fpsDecode: fpsDecode ?? this.fpsDecode,
96 | fpsOutput: fpsOutput ?? this.fpsOutput,
97 | downloadSpeed: downloadSpeed ?? this.downloadSpeed,
98 | bitrate: bitrate ?? this.bitrate
99 | );
100 | }
101 |
102 | @override
103 | String toString() {
104 | return '$runtimeType('
105 | 'duration: $duration, '
106 | 'position: $position, '
107 | 'buffered: $bufferedPrecent, '
108 | 'isPlaying: $isPlaying, '
109 | 'isLooping: $isLooping, '
110 | 'isBuffering: $isBuffering'
111 | 'volume: $volume, '
112 | 'errorDescription: $errMsg)';
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: ijkplayer
2 | description: A new flutter plugin project.
3 | version: 0.0.1
4 | author:
5 | homepage:
6 |
7 | environment:
8 | sdk: ">=2.0.0-dev.68.0 <3.0.0"
9 |
10 | dependencies:
11 | flutter:
12 | sdk: flutter
13 |
14 | # For information on the generic Dart part of this file, see the
15 | # following page: https://www.dartlang.org/tools/pub/pubspec
16 |
17 | # The following section is specific to Flutter.
18 | flutter:
19 | # This section identifies this Flutter project as a plugin project.
20 | # The androidPackage and pluginClass identifiers should not ordinarily
21 | # be modified. They are used by the tooling to maintain consistency when
22 | # adding or updating assets for this project.
23 | plugin:
24 | androidPackage: cn.ugle.plugin.ijkplayer
25 | pluginClass: IJKPlayerPlugin
26 |
27 | # To add assets to your plugin package, add an assets section, like this:
28 | # assets:
29 | # - images/a_dot_burr.jpeg
30 | # - images/a_dot_ham.jpeg
31 | #
32 | # For details regarding assets in packages, see
33 | # https://flutter.io/assets-and-images/#from-packages
34 | #
35 | # An image asset can refer to one or more resolution-specific "variants", see
36 | # https://flutter.io/assets-and-images/#resolution-aware.
37 |
38 | # To add custom fonts to your plugin package, add a fonts section here,
39 | # in this "flutter" section. Each entry in this list should have a
40 | # "family" key with the font family name, and a "fonts" key with a
41 | # list giving the asset and other descriptors for the font. For
42 | # example:
43 | # fonts:
44 | # - family: Schyler
45 | # fonts:
46 | # - asset: fonts/Schyler-Regular.ttf
47 | # - asset: fonts/Schyler-Italic.ttf
48 | # style: italic
49 | # - family: Trajan Pro
50 | # fonts:
51 | # - asset: fonts/TrajanPro.ttf
52 | # - asset: fonts/TrajanPro_Bold.ttf
53 | # weight: 700
54 | #
55 | # For details regarding fonts in packages, see
56 | # https://flutter.io/custom-fonts/#from-packages
57 |
--------------------------------------------------------------------------------
/snapshot/1545422510.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/snapshot/1545422510.png
--------------------------------------------------------------------------------
/snapshot/IMG_0260.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/snapshot/IMG_0260.JPG
--------------------------------------------------------------------------------
/snapshot/IMG_0261.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/snapshot/IMG_0261.JPG
--------------------------------------------------------------------------------
/snapshot/IMG_0262.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/snapshot/IMG_0262.JPG
--------------------------------------------------------------------------------
/snapshot/IMG_0263.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/snapshot/IMG_0263.JPG
--------------------------------------------------------------------------------
/snapshot/IMG_0264.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/snapshot/IMG_0264.JPG
--------------------------------------------------------------------------------
/snapshot/IMG_0265.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/snapshot/IMG_0265.JPG
--------------------------------------------------------------------------------
/snapshot/IMG_0266.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/snapshot/IMG_0266.JPG
--------------------------------------------------------------------------------
/snapshot/IMG_0267.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/snapshot/IMG_0267.JPG
--------------------------------------------------------------------------------
/snapshot/QQ图片20190322205804.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/snapshot/QQ图片20190322205804.jpg
--------------------------------------------------------------------------------
/snapshot/QQ图片20190322205813.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/snapshot/QQ图片20190322205813.jpg
--------------------------------------------------------------------------------
/snapshot/QQ截图20190216150720.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/An-uking/Flutter_IJKPlayer/b5bc06f3ccca1262ac56d76e6e09aa3cdd553ac0/snapshot/QQ截图20190216150720.png
--------------------------------------------------------------------------------