├── .all-contributorsrc
├── .gitattributes
├── .github
└── ISSUE_TEMPLATE
│ ├── -------.md
│ ├── ----.md
│ ├── --bug.md
│ ├── bug_report.md
│ ├── feature_request.md
│ └── need-help.md
├── .gitignore
├── .metadata
├── .vscode
├── launch.json
└── settings.json
├── BUG.md
├── CHANGELOG.md
├── CONTRIBUTING.md
├── FAQ.md
├── LICENSE
├── README-EN.md
├── README.md
├── TODOLIST.md
├── android
├── .classpath
├── .gitignore
├── .project
├── .settings
│ └── org.eclipse.buildship.core.prefs
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── proguard-rules.pro
├── settings.gradle
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ ├── top
│ │ │ └── kikt
│ │ │ │ └── ijkplayer
│ │ │ │ ├── FileMediaDataSource.java
│ │ │ │ ├── Ijk.kt
│ │ │ │ ├── IjkManager.kt
│ │ │ │ ├── Log.kt
│ │ │ │ ├── NotifyChannel.kt
│ │ │ │ └── entity
│ │ │ │ ├── IjkOption.kt
│ │ │ │ └── Info.kt
│ │ └── tv
│ │ │ └── danmaku
│ │ │ └── ijk
│ │ │ └── media
│ │ │ └── player
│ │ │ ├── AbstractMediaPlayer.java
│ │ │ ├── AndroidMediaPlayer.java
│ │ │ ├── IMediaPlayer.java
│ │ │ ├── ISurfaceTextureHolder.java
│ │ │ ├── ISurfaceTextureHost.java
│ │ │ ├── IjkLibLoader.java
│ │ │ ├── IjkMediaCodecInfo.java
│ │ │ ├── IjkMediaMeta.java
│ │ │ ├── IjkMediaPlayer.java
│ │ │ ├── IjkTimedText.java
│ │ │ ├── MediaInfo.java
│ │ │ ├── MediaPlayerProxy.java
│ │ │ ├── TextureMediaPlayer.java
│ │ │ ├── annotations
│ │ │ ├── AccessedByNative.java
│ │ │ └── CalledByNative.java
│ │ │ ├── exceptions
│ │ │ └── IjkMediaException.java
│ │ │ ├── ffmpeg
│ │ │ └── FFmpegApi.java
│ │ │ ├── misc
│ │ │ ├── AndroidMediaFormat.java
│ │ │ ├── AndroidTrackInfo.java
│ │ │ ├── IAndroidIO.java
│ │ │ ├── IMediaDataSource.java
│ │ │ ├── IMediaFormat.java
│ │ │ ├── ITrackInfo.java
│ │ │ ├── IjkMediaFormat.java
│ │ │ └── IjkTrackInfo.java
│ │ │ └── pragma
│ │ │ ├── DebugLog.java
│ │ │ └── Pragma.java
│ │ ├── kotlin
│ │ └── top
│ │ │ └── kikt
│ │ │ └── ijkplayer
│ │ │ └── IjkplayerPlugin.kt
│ │ └── libs
│ │ ├── arm64-v8a
│ │ ├── libijkffmpeg.so
│ │ ├── libijkplayer.so
│ │ └── libijksdl.so
│ │ ├── armeabi-v7a
│ │ ├── libijkffmpeg.so
│ │ ├── libijkplayer.so
│ │ └── libijksdl.so
│ │ ├── x86
│ │ ├── libijkffmpeg.so
│ │ ├── libijkplayer.so
│ │ └── libijksdl.so
│ │ └── x86_64
│ │ ├── libijkffmpeg.so
│ │ ├── libijkplayer.so
│ │ └── libijksdl.so
└── switch_env.sh
├── compile-cn.md
├── compile.md
├── example
├── .flutter-plugins-dependencies
├── .gitignore
├── .metadata
├── README.md
├── android
│ ├── .project
│ ├── .settings
│ │ └── org.eclipse.buildship.core.prefs
│ ├── app
│ │ ├── .classpath
│ │ ├── .project
│ │ ├── .settings
│ │ │ └── org.eclipse.buildship.core.prefs
│ │ ├── arm64.gradle
│ │ ├── build.gradle
│ │ ├── proguard-rules.pro
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ │ └── com
│ │ │ │ │ └── example
│ │ │ │ │ └── ijkplayer_example
│ │ │ │ │ └── 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
│ │ │ └── profile
│ │ │ └── AndroidManifest.xml
│ ├── build.gradle
│ ├── example-key.jks
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ └── settings.gradle
├── assets
│ └── sample1.mp4
├── ios
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ ├── Flutter.podspec
│ │ ├── Release.xcconfig
│ │ └── flutter_export_environment.sh
│ ├── Podfile
│ ├── Podfile.lock
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── 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
│ ├── const
│ │ ├── resource.dart
│ │ └── video_datasource.dart
│ ├── i18n
│ │ ├── cn.dart
│ │ ├── en.dart
│ │ └── i18n.dart
│ ├── main.dart
│ ├── page
│ │ ├── asset_page.dart
│ │ ├── auto_full_screen.dart
│ │ ├── controller_stream_use.dart
│ │ ├── custom_ijk_opt_page.dart
│ │ ├── developing
│ │ │ ├── crash_on_set_src_page.dart
│ │ │ ├── develop_index.dart
│ │ │ ├── develop_prepare_page.dart
│ │ │ ├── live_interruption_page.dart
│ │ │ ├── new_full_screen_page.dart
│ │ │ ├── src_error_page.dart
│ │ │ └── test_hide_system_bar.dart
│ │ ├── dialog_video_page.dart
│ │ ├── error_url.dart
│ │ ├── full_screen.dart
│ │ ├── gallery_page.dart
│ │ ├── ijk_status_page.dart
│ │ ├── in_overlay_page.dart
│ │ ├── index.dart
│ │ ├── network.dart
│ │ ├── paging_page.dart
│ │ ├── screen_shot_page.dart
│ │ ├── simple_use.dart
│ │ ├── speed_page.dart
│ │ └── video_list.dart
│ └── utils
│ │ └── options_utils.dart
├── pubspec.yaml
└── test
│ └── widget_test.dart
├── ijkplayer.iml
├── ios
├── .gitignore
├── Assets
│ └── .gitkeep
├── Classes
│ ├── CoolFlutterIJK.h
│ ├── CoolFlutterIJK.m
│ ├── CoolFlutterIjkManager.h
│ ├── CoolFlutterIjkManager.m
│ ├── CoolFlutterResult.h
│ ├── CoolFlutterResult.m
│ ├── CoolIjkNotifyChannel.h
│ ├── CoolIjkNotifyChannel.m
│ ├── CoolIjkOption.h
│ ├── CoolIjkOption.m
│ ├── CoolVideoInfo.h
│ ├── CoolVideoInfo.m
│ ├── FlutterViewController+CoolStatusBarHidden.h
│ ├── FlutterViewController+CoolStatusBarHidden.m
│ ├── IjkplayerPlugin.h
│ └── IjkplayerPlugin.m
├── flutter_ijkplayer.dev.podspec
├── flutter_ijkplayer.podspec
├── flutter_ijkplayer.prod.podspec
└── switch_local.sh
├── lib
├── flutter_ijkplayer.dart
└── src
│ ├── controller
│ ├── controller.dart
│ ├── datasoure.dart
│ ├── enums.dart
│ ├── ijk_event_channel.dart
│ ├── ijkplayer_controller_mixin.dart
│ └── plugin.dart
│ ├── engine
│ ├── ijk_controller_manager.dart
│ └── manager.dart
│ ├── entity
│ ├── options.dart
│ └── video_info.dart
│ ├── error.dart
│ ├── helper
│ ├── config.dart
│ ├── full_screen_helper.dart
│ ├── logutil.dart
│ ├── time_helper.dart
│ └── ui_helper.dart
│ ├── ijkplayer.dart
│ ├── route
│ └── fullscreen_route.dart
│ └── widget
│ ├── controller_widget_builder.dart
│ ├── full_screen.part.dart
│ ├── ijk_status_widget.dart
│ ├── ijkplayer_builder.dart
│ └── progress_bar.dart
├── package.json
├── pubspec.yaml
├── svg
└── logo.html
└── yarn.lock
/.all-contributorsrc:
--------------------------------------------------------------------------------
1 | {
2 | "projectName": "flutter_ijkplayer",
3 | "projectOwner": "caijinglong",
4 | "repoType": "github",
5 | "repoHost": "https://github.com",
6 | "files": [
7 | "CONTRIBUTING.md"
8 | ],
9 | "imageSize": 100,
10 | "commit": true,
11 | "commitConvention": "gitmoji",
12 | "contributors": [
13 | {
14 | "login": "CaiJingLong",
15 | "name": "Caijinglong",
16 | "avatar_url": "https://avatars0.githubusercontent.com/u/14145407?v=4",
17 | "profile": "https://www.kikt.top",
18 | "contributions": [
19 | "code",
20 | "design"
21 | ]
22 | },
23 | {
24 | "login": "gwuhaolin",
25 | "name": "浩麟",
26 | "avatar_url": "https://avatars2.githubusercontent.com/u/5773264?v=4",
27 | "profile": "https://github.com/gwuhaolin",
28 | "contributions": [
29 | "code"
30 | ]
31 | }
32 | ],
33 | "contributorsPerLine": 7
34 | }
35 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ios/IJKMediaFramework.framework/IJKMediaFramework filter=lfs diff=lfs merge=lfs -text
2 | *.java linguist-language=dart
3 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/-------.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 如何使用这个库
3 | about: 关于这个库使用上的问题
4 | title: '[Need help]'
5 | labels: help wanted, wait confirm
6 | assignees: ''
7 | ---
8 |
9 | ** 简单描述 **
10 | 简单描述你遇到的问题
11 |
12 | ** 辅助信息 **
13 |
14 | 添加一些截图/设计图以便于可以让别人理解你遇到的问题
15 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/----.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 功能请求
3 | about: 关于功能的请求或建议
4 | title: '[Feature request]'
5 | labels: wait confirm
6 | assignees: ''
7 | ---
8 |
9 | **功能描述**
10 |
11 | **添加辅助信息帮助明确**
12 |
13 | 添加原型/截图/UI 设计图等方式帮助开发者明确需求,以评估是否应该是插件做的事情
14 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/--bug.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 报告bug
3 | about: 报告一个bug以帮助开发者定位,或解决问题
4 | title: '[Bug]'
5 | labels: wait confirm
6 | assignees: ''
7 | ---
8 |
9 | **描述一下你遇到的 bug**
10 | 描述一下你的 bug
11 |
12 | **重现 bug**
13 |
14 | 通过什么样的步骤可以重现:
15 |
16 | 1. Go to '...'
17 | 2. Click on '....'
18 | 3. Scroll down to '....'
19 | 4. See error
20 |
21 | **日志**
22 |
23 | ```
24 |
25 | ```
26 |
27 | **flutter 版本**
28 | 使用 `$ flutter doctor -v` 并粘贴详细的信息到这里,如果是特定机型的 bug,请包含设备信息
29 |
30 | ```bash
31 |
32 | ```
33 |
34 | **插件版本**
35 |
36 | **截图**
37 | 如果有,请截图
38 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: "[Bug report]"
5 | labels: wait confirm
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Screenshots**
21 | If applicable, add screenshots to help explain your problem.
22 |
23 | **Flutter version**
24 | Use `$ flutter doctor -v` and paste info to this.
25 |
26 | **Plugin version**
27 | Example: 0.x.x
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: "[Feature Request]"
5 | labels: wait confirm
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Simple description **
11 |
12 | **Describe the solution you'd like**
13 | Explain your detailed requirements in order to assess whether you will join the development plan.
14 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/need-help.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Need help
3 | about: Describe your needs, see if anyone can help you.
4 | title: "[Need help]"
5 | labels: help wanted, wait confirm
6 | assignees: ''
7 |
8 | ---
9 |
10 | Describe your needs
11 |
12 | If possible, add prototypes / designs and other supporting documents to help others understand your needs.
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .dart_tool/
3 |
4 | .packages
5 | .pub/
6 |
7 | build/
8 | .idea
9 | doc/
10 | pubspec.lock
11 | fvm
12 |
13 | node_modules
--------------------------------------------------------------------------------
/.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: 7fc14a55af64462763d28abfb4e610086c6e0f39
8 | channel: dev
9 |
10 | project_type: plugin
11 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // 使用 IntelliSense 了解相关属性。
3 | // 悬停以查看现有属性的描述。
4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "Flutter",
9 | "request": "launch",
10 | "type": "dart",
11 | "program": "example/lib/main.dart"
12 | }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "dart.flutterSdkPath": "/Users/caijinglong/Library/Flutter/flutter_dev"
3 | }
--------------------------------------------------------------------------------
/BUG.md:
--------------------------------------------------------------------------------
1 | ## all
2 |
3 | - [x] 全屏模式可自定义
4 |
5 | ## iOS
6 |
7 | - [x] 全屏模式在 iphone xs max 上未全屏
8 |
9 | ## android
10 |
11 | - [x] 一些 m3u8 无声音
12 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 0.3.6
2 |
3 | New feature
4 |
5 | - Support playing video directly through photo_manager URL.
6 |
7 | Fix:
8 |
9 | - iOS
10 |
11 | - Support hardware decoding in iOS.
12 | - Fix hardware decoding memory leaks error.
13 | - Support screenshot in hardware-decoding.
14 |
15 | - android
16 | - [#204](https://github.com/CaiJingLong/flutter_ijkplayer/pull/204)
17 |
18 | ## 0.3.5+1
19 |
20 | To adapt to the new version of the flutter sdk check kt plugin.
21 |
22 | ## 0.3.5
23 |
24 | Feature:
25 |
26 | - Auto hide the status bar when full screen and show in exit.
27 | - Add callback when the full screen state changes for `DefaultIJKControllerWidget`.
28 |
29 | ## 0.3.4
30 |
31 | Fix:
32 |
33 | - The fps of the autoplayed datasource is always 3.
34 |
35 | ## 0.3.3
36 |
37 | Migrate ios pod library from github to azure.
38 |
39 | There is no code modification compared to 0.3.2.
40 |
41 | ## 0.3.2
42 |
43 | Fix:
44 |
45 | - Touch gesture problem
46 | - Missing plugin error message
47 |
48 | ## 0.3.1
49 |
50 | Update:
51 |
52 | - Use a new full screen type: Now, use `RotateBox` to rotate IjkPlayer.
53 |
54 | ## 0.3.0
55 |
56 | Fix: [#91](https://github.com/CaiJingLong/flutter_ijkplayer/issues/91)
57 |
58 | - Fix: for android annotation @Nonnull
59 |
60 | ## 0.2.9
61 |
62 | Fix: [#87](https://github.com/CaiJingLong/flutter_ijkplayer/issues/87)
63 |
64 | ## 0.2.8+1
65 |
66 | Update pubspec and some Readme.
67 |
68 | ## 0.2.8
69 |
70 | New feature:
71 |
72 | - Now, user can setSpeed.
73 |
74 | Fix:
75 |
76 | - About setDataSource and autoPlay.
77 |
78 | ## 0.2.7
79 |
80 | Fix bug:
81 |
82 | - some m3u8 no sound.
83 | - some asset cannot play.
84 |
85 | ## 0.2.6
86 |
87 | Fix bug:
88 |
89 | - Possible null pointer exceptions
90 |
91 | ## 0.2.5
92 |
93 | Fix bug:
94 |
95 | Problems in `TabView`.
96 |
97 | ## 0.2.4
98 |
99 | fix bug:
100 |
101 | - set datasource and play error.
102 | - iOS xs max fullscreen problem.
103 |
104 | new:
105 |
106 | - Customizing the interface affects the full screen.
107 |
108 | ## 0.2.3
109 |
110 | Fixed the problem that a project without kotlin could not be compiled.
111 |
112 | ## 0.2.2
113 |
114 | Add `setIjkPlayerOptions` and `addIjkPlayerOptions`.
115 |
116 | iOS podspec add `s.static_framework = true`
117 |
118 | ## 0.2.1
119 |
120 | Recompile android so library.
121 |
122 | ## 0.2.0
123 |
124 | Add `StatusWidgetBuilder` params.
125 |
126 | Update volume and brightness icon
127 |
128 | ## 0.1.9
129 |
130 | add screen shot method.
131 |
132 | ## 0.1.8
133 |
134 | Screen rotation and full screen control code.
135 |
136 | ## 0.1.7
137 |
138 | Fixed some video decoding problems.
139 |
140 | ## 0.1.6
141 |
142 | - add problem left vertical gesture to control brightness.
143 |
144 | - fix some problem.
145 |
146 | ## 0.1.5
147 |
148 | update iOS framework
149 |
150 | add some property
151 |
152 | ## 0.1.4
153 |
154 | Use [GSYVideoPlayer](https://github.com/CarGuo/GSYVideoPlayer) android ex so
155 |
156 | ## 0.1.3
157 |
158 | Use [GSYVideoPlayer](https://github.com/CarGuo/GSYVideoPlayer) android \*.so
159 |
160 | ## 0.1.2
161 |
162 | fix ios fps problem.
163 |
164 | ## 0.1.1
165 |
166 | fix some bug
167 |
168 | ## 0.1.0
169 |
170 | first version
171 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Contributors ✨
2 |
3 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
4 |
5 |
6 |
7 |
8 |
14 |
15 |
16 |
17 |
18 |
19 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
20 |
--------------------------------------------------------------------------------
/FAQ.md:
--------------------------------------------------------------------------------
1 | # FAQ
2 |
3 | ## iOS
4 |
5 | ### About get cocoapod error
6 |
7 | Q: Use the 0.2.3 version of FlutterIJK error in iOS.
8 | A: Use next method:
9 |
10 | ```bash
11 | pod cache clean FlutterIJK
12 | ```
13 |
14 | Remove your FlutterIJK version.
15 | And rerun `pod install`
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Caijinglong
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.
--------------------------------------------------------------------------------
/TODOLIST.md:
--------------------------------------------------------------------------------
1 | # TodoList
2 |
3 | - [x] 控制器逻辑
4 | - [x] 设置数据源
5 | - [x] 网络
6 | - [x] 设置请求头
7 | - [x] 本地
8 | - [x] 资产
9 | - [x] 播放
10 | - [x] 暂停
11 | - [x] 停止
12 | - [x] 释放资源
13 | - [x] 控制音量
14 | - [x] 监听播放完成
15 | - [x] 控制系统音量
16 | - [x] 修复 iOS 系统音量与逻辑相反的问题
17 | - [x] 修复 iOS 系统音量出现系统弹窗的问题
18 | - [x] 修复 iOS 系统音量出现时视频明显卡顿的问题
19 | - [x] 获取视频信息
20 | - [x] 宽高
21 | - [x] 当前播放进度
22 | - [x] 总时长
23 | - [x] 视频方向
24 | - [x] 视频播放速度
25 | - [x] tcp 速度
26 | - [ ] 当前视频编解码器(作为未来备选方案,目前 android 端可获取,iOS 端只有解码器 id 没有名字)
27 | - [ ] 视频
28 | - [ ] 音频
29 | - [x] 帧数
30 | - [x] android
31 | - [ ] iOS (目前永远是 0,获取的是 GL_view 的 fps)
32 | - [x] 控制亮度
33 | - [x] 逻辑方法
34 | - [x] 界面实现
35 | - [x] 屏幕方向锁定 : 这个指当前页面支持什么方向的应用
36 | - [ ] iPad 无效,暂不知原因
37 | - [x] 屏幕旋转: 这个指强制当前屏幕旋转至哪个方向
38 | - [ ] iPad 无效,暂不知原因
39 | - [x] 截图
40 | - [ ] 悬浮窗中播放
41 | - [ ] 悬浮窗的 UI 控制器
42 | - [ ] 自定义 UI
43 | - [x] 视频播放出错时的回调通知
44 | - [x] 默认控制器 UI
45 | - [x] 进度条
46 | - [x] 播放/暂停按钮
47 | - [x] 全屏横向滑动进度
48 | - [x] 拖动进度条快速调节进度
49 | - [x] 逻辑部分实现
50 | - [x] UI 提示
51 | - [x] 纵向滑动音量
52 | - [x] 单击显示/隐藏界面
53 | - [x] 双击播放/暂停
54 | - [x] 使用选项切换音量的控制是系统音量还是资源音量
55 | - [x] 允许根据情况禁用各种控制手势
56 | - [x] 当一个视频是直播视频时,进度条应该隐藏,且无拖动进度相关手势
57 | - [x] 全屏切换
58 | - [x] UI(控制器 UI 内)
59 | - [x] android
60 | - [x] iOS
61 | - [x] 利用 ShowDialog 开发一个全屏的播放界面,不仅仅在 Example 中
62 | - [x] 根据屏幕宽高确定是横屏全屏还是竖屏全屏(比如:常规电影是横屏,常规自拍类视频为竖屏)
63 | - [ ] 全屏的界面也接受自定义 UI 的参数
64 | - [ ] 网络视频发生缓冲的情况,应在 UI 上有所反馈
65 | - [x] 根据视频角度自动旋转
66 | - [x] 保证视频图像宽高比不失真
67 | - [x] 允许自定义控制器 UI
68 | - [ ] 未开始播放时的界面
69 | - [ ] 默认
70 | - [ ] 允许自定义
71 | - [ ] 完善示例代码
72 | - [x] 播放网络
73 | - [x] 播放相册
74 | - [x] 播放 asset
75 | - [ ] 设置选项的使用
76 | - [x] 切换全屏播放的示例代码
77 | - [x] 在列表中(ListView)
78 | - [x] 视频竖向分页滑动
79 | - [x] 在悬浮窗中播放
80 | - [x] 悬浮窗的 UI 控制器
81 | - [x] iOS 部分视频无法显示图像的问题: 可能很长时间内都无法解决
82 | - [x] 支持在 dart 端初始化 ijkPlayer 播放器的 option
83 | - [x] android
84 | - [x] iOS
85 |
--------------------------------------------------------------------------------
/android/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/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/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | ijkplayer
4 | Project ijkplayer created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.buildship.core.gradleprojectbuilder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.jdt.core.javanature
21 | org.eclipse.buildship.core.gradleprojectnature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/android/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | connection.project.dir=
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | group 'top.kikt.ijkplayer'
2 | version '1.0-SNAPSHOT'
3 |
4 | buildscript {
5 | ext.kotlin_version = '1.3.21'
6 | repositories {
7 | google()
8 | jcenter()
9 | }
10 |
11 | dependencies {
12 | classpath 'com.android.tools.build:gradle:3.3.2'
13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14 | }
15 | }
16 |
17 | rootProject.allprojects {
18 | repositories {
19 | google()
20 | jcenter()
21 | }
22 | }
23 |
24 | apply plugin: 'com.android.library'
25 | apply plugin: 'kotlin-android'
26 |
27 | android {
28 | compileSdkVersion 29
29 |
30 | defaultConfig {
31 | minSdkVersion 16
32 | consumerProguardFiles 'proguard-rules.pro'
33 | }
34 | lintOptions {
35 | disable 'InvalidPackage'
36 | }
37 |
38 | sourceSets.main {
39 | jniLibs.srcDirs 'src/main/libs'
40 | java.srcDirs = ['src/main/java', 'src/main/kotlin']
41 | }
42 |
43 | buildTypes {
44 | profile {
45 | initWith debug
46 | }
47 | }
48 | }
49 |
50 |
51 | dependencies {
52 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
53 | }
54 | repositories {
55 | mavenCentral()
56 | }
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.enableR8=true
3 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
6 |
--------------------------------------------------------------------------------
/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 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/android/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | -keep class tv.danmaku.ijk.media.player.** {
2 | *;
3 | }
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'ijkplayer'
2 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/src/main/java/top/kikt/ijkplayer/FileMediaDataSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Bilibili
3 | * Copyright (C) 2015 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package top.kikt.ijkplayer;
19 |
20 | import java.io.File;
21 | import java.io.IOException;
22 | import java.io.RandomAccessFile;
23 |
24 | import tv.danmaku.ijk.media.player.misc.IMediaDataSource;
25 |
26 | public class FileMediaDataSource implements IMediaDataSource {
27 | private RandomAccessFile mFile;
28 | private long mFileSize;
29 | private File originFile;
30 |
31 | public FileMediaDataSource(File file) throws IOException {
32 | this.originFile =file;
33 | mFile = new RandomAccessFile(file, "r");
34 | mFileSize = mFile.length();
35 | }
36 |
37 | @Override
38 | public int readAt(long position, byte[] buffer, int offset, int size) throws IOException {
39 | if (mFile.getFilePointer() != position)
40 | mFile.seek(position);
41 |
42 | if (size == 0)
43 | return 0;
44 |
45 | return mFile.read(buffer, 0, size);
46 | }
47 |
48 | @Override
49 | public long getSize() throws IOException {
50 | return mFileSize;
51 | }
52 |
53 | @Override
54 | public void close() throws IOException {
55 | if (originFile.exists()) {
56 | mFileSize = 0;
57 | mFile.close();
58 | }
59 | mFile = null;
60 |
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/android/src/main/java/top/kikt/ijkplayer/IjkManager.kt:
--------------------------------------------------------------------------------
1 | package top.kikt.ijkplayer
2 |
3 | /// create 2019/3/7 by cai
4 |
5 |
6 | import io.flutter.plugin.common.PluginRegistry
7 | import java.util.*
8 |
9 | class IjkManager(private val registrar: PluginRegistry.Registrar) {
10 | private val ijkList = ArrayList()
11 |
12 | fun create(options: Map): Ijk {
13 | val ijk = Ijk(registrar,options)
14 | ijkList.add(ijk)
15 | return ijk
16 | }
17 |
18 | private fun findIJK(id: Long): Ijk? {
19 | return ijkList.find { it.id == id }
20 | }
21 |
22 | fun dispose(id: Long) {
23 | val ijk = findIJK(id) ?: return
24 | ijkList.remove(ijk)
25 | ijk.dispose()
26 | }
27 |
28 | fun disposeAll() {
29 | for (ijk in ijkList.toList()) {
30 | ijkList.remove(ijk)
31 | ijk.dispose()
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/android/src/main/java/top/kikt/ijkplayer/Log.kt:
--------------------------------------------------------------------------------
1 | package top.kikt.ijkplayer
2 |
3 | import android.util.Log
4 |
5 | var showLog = true
6 |
7 | fun Any.logi(any: Any?) {
8 | if (showLog) {
9 | Log.i(this::class.java.simpleName, any.toString())
10 | }
11 | }
--------------------------------------------------------------------------------
/android/src/main/java/top/kikt/ijkplayer/NotifyChannel.kt:
--------------------------------------------------------------------------------
1 | package top.kikt.ijkplayer
2 |
3 | import io.flutter.plugin.common.MethodChannel
4 | import io.flutter.plugin.common.PluginRegistry
5 | import tv.danmaku.ijk.media.player.IMediaPlayer
6 |
7 | class NotifyChannel(val registry: PluginRegistry.Registrar, val textureId: Long, val ijk: Ijk) {
8 |
9 | private val player
10 | get() = ijk.mediaPlayer
11 |
12 | private val channel = MethodChannel(
13 | registry.messenger(),
14 | "top.kikt/ijkplayer/event/$textureId"
15 | )
16 | // private val channel = Temp()
17 |
18 | private val info
19 | get() = ijk.getInfo().toMap()
20 |
21 | init {
22 | player.setOnPreparedListener {
23 | logi("prepare $info")
24 | player.trackInfo.forEach {
25 |
26 | }
27 | channel.invokeMethod("prepare", info)
28 | }
29 | player.setOnCompletionListener {
30 | logi("completion $info")
31 | channel.invokeMethod("finish", info)
32 | }
33 | player.setOnBufferingUpdateListener { mp, percent ->
34 | /// 在线视频缓冲
35 | logi("completion buffer update $info $percent")
36 | }
37 | player.setOnSeekCompleteListener {
38 | logi("onSeekCompletion $info")
39 | }
40 | player.setOnErrorListener { mp, what, extra ->
41 | channel.invokeMethod("error", what)
42 | logi("onError $what , extra = $extra")
43 | false
44 | }
45 | player.setOnInfoListener { mp, what, extra ->
46 | logi("onInfoListener $what, extra = $extra, isPlaying = ${player.isPlaying} ")
47 | when (what) {
48 | IMediaPlayer.MEDIA_INFO_AUDIO_DECODED_START, IMediaPlayer.MEDIA_INFO_VIDEO_DECODED_START -> {
49 | // channel.invokeMethod("playStateChange", info)
50 | }
51 | IMediaPlayer.MEDIA_INFO_VIDEO_ROTATION_CHANGED -> {
52 | ijk.degree = extra
53 | channel.invokeMethod("rotateChanged", info)
54 | }
55 | }
56 | false
57 | }
58 | player.setOnNativeInvokeListener { what, args ->
59 | logi("onNativeInvoke $what")
60 | false
61 | }
62 | player.setOnControlMessageListener {
63 | logi("onController message $it, isPlaying = ${player.isPlaying}")
64 | ""
65 | }
66 | }
67 |
68 | fun dispose() {
69 | player.resetListeners()
70 | }
71 |
72 | }
--------------------------------------------------------------------------------
/android/src/main/java/top/kikt/ijkplayer/entity/IjkOption.kt:
--------------------------------------------------------------------------------
1 | package top.kikt.ijkplayer.entity
2 |
3 | /// create 2019/4/12 by cai
4 |
5 | class IjkOption(option: Map<*, *>) {
6 |
7 | lateinit var type: Type
8 | lateinit var key: String
9 | lateinit var value: Any
10 |
11 | var isInit = true
12 |
13 | init {
14 | val type = option["category"]
15 | if (type is Int) {
16 | this.type = convertIntToType(type)
17 | }
18 |
19 | val key = option["key"]
20 | if (key is String) {
21 | this.key = key
22 | isInit = isInit and true
23 | }
24 |
25 | option["value"]?.let {
26 | this.value = it
27 | isInit = isInit and true
28 | }
29 |
30 | isInit = (type is Int) and (key is String) and (option.containsKey("value"))
31 | }
32 |
33 | private fun convertIntToType(typeInt: Int): Type {
34 | return when (typeInt) {
35 | 0 -> Type.Format
36 | 1 -> Type.Codec
37 | 2 -> Type.Sws
38 | 3 -> Type.Player
39 | else -> Type.Other
40 | }
41 | }
42 |
43 | enum class Type {
44 | Format,
45 | Codec,
46 | Sws,
47 | Player,
48 | Other,
49 | }
50 | }
--------------------------------------------------------------------------------
/android/src/main/java/top/kikt/ijkplayer/entity/Info.kt:
--------------------------------------------------------------------------------
1 | package top.kikt.ijkplayer.entity
2 |
3 | /// create 2019/3/15 by cai
4 | data class Info(
5 | val duration: Double,
6 | val currentPosition: Double,
7 | val width: Int,
8 | val height: Int,
9 | val isPlaying: Boolean,
10 | val degree: Int = 0,
11 | val tcpSpeed: Long = 0,
12 | val outputFps: Float = 0f
13 | // val decodeFps: Float = 0f
14 | ) {
15 |
16 | fun toMap(): Map {
17 | val map = HashMap()
18 | map["duration"] = duration
19 | map["currentPosition"] = currentPosition
20 | map["width"] = width
21 | map["height"] = height
22 | map["isPlaying"] = isPlaying
23 | map["degree"] = degree
24 | map["tcpSpeed"] = tcpSpeed
25 | map["outputFps"] = outputFps
26 | // map["decodeFps"] = decodeFps
27 | return map
28 | }
29 |
30 | }
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/ISurfaceTextureHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Bilibili
3 | * Copyright (C) 2015 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player;
19 |
20 | import android.graphics.SurfaceTexture;
21 |
22 | public interface ISurfaceTextureHolder {
23 | void setSurfaceTexture(SurfaceTexture surfaceTexture);
24 |
25 | SurfaceTexture getSurfaceTexture();
26 |
27 | void setSurfaceTextureHost(ISurfaceTextureHost surfaceTextureHost);
28 | }
29 |
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/ISurfaceTextureHost.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Bilibili
3 | * Copyright (C) 2015 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player;
19 |
20 | import android.graphics.SurfaceTexture;
21 |
22 | public interface ISurfaceTextureHost {
23 | void releaseSurfaceTexture(SurfaceTexture surfaceTexture);
24 | }
25 |
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/IjkLibLoader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013-2014 Bilibili
3 | * Copyright (C) 2013-2014 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player;
19 |
20 | public interface IjkLibLoader {
21 | void loadLibrary(String libName) throws UnsatisfiedLinkError,
22 | SecurityException;
23 | }
24 |
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/IjkTimedText.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Zheng Yuan
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package tv.danmaku.ijk.media.player;
18 |
19 | import android.graphics.Rect;
20 | import java.lang.String;
21 |
22 | public final class IjkTimedText {
23 |
24 | private Rect mTextBounds = null;
25 | private String mTextChars = null;
26 |
27 | public IjkTimedText(Rect bounds, String text) {
28 | mTextBounds = bounds;
29 | mTextChars = text;
30 | }
31 |
32 | public Rect getBounds() {
33 | return mTextBounds;
34 | }
35 |
36 | public String getText() {
37 | return mTextChars;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/MediaInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013-2014 Bilibili
3 | * Copyright (C) 2013-2014 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player;
19 |
20 | public class MediaInfo {
21 | public String mMediaPlayerName;
22 |
23 | public String mVideoDecoder;
24 | public String mVideoDecoderImpl;
25 |
26 | public String mAudioDecoder;
27 | public String mAudioDecoderImpl;
28 |
29 | public IjkMediaMeta mMeta;
30 | }
31 |
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/TextureMediaPlayer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Bilibili
3 | * Copyright (C) 2015 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player;
19 |
20 | import android.annotation.TargetApi;
21 | import android.graphics.SurfaceTexture;
22 | import android.os.Build;
23 | import android.view.Surface;
24 | import android.view.SurfaceHolder;
25 |
26 | @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
27 | public class TextureMediaPlayer extends MediaPlayerProxy implements IMediaPlayer, ISurfaceTextureHolder {
28 | private SurfaceTexture mSurfaceTexture;
29 | private ISurfaceTextureHost mSurfaceTextureHost;
30 |
31 | public TextureMediaPlayer(IMediaPlayer backEndMediaPlayer) {
32 | super(backEndMediaPlayer);
33 | }
34 |
35 | public void releaseSurfaceTexture() {
36 | if (mSurfaceTexture != null) {
37 | if (mSurfaceTextureHost != null) {
38 | mSurfaceTextureHost.releaseSurfaceTexture(mSurfaceTexture);
39 | } else {
40 | mSurfaceTexture.release();
41 | }
42 | mSurfaceTexture = null;
43 | }
44 | }
45 |
46 | //--------------------
47 | // IMediaPlayer
48 | //--------------------
49 | @Override
50 | public void reset() {
51 | super.reset();
52 | releaseSurfaceTexture();
53 | }
54 |
55 | @Override
56 | public void release() {
57 | super.release();
58 | releaseSurfaceTexture();
59 | }
60 |
61 | @Override
62 | public void setDisplay(SurfaceHolder sh) {
63 | if (mSurfaceTexture == null)
64 | super.setDisplay(sh);
65 | }
66 |
67 | @Override
68 | public void setSurface(Surface surface) {
69 | if (mSurfaceTexture == null)
70 | super.setSurface(surface);
71 | }
72 |
73 | //--------------------
74 | // ISurfaceTextureHolder
75 | //--------------------
76 |
77 | @Override
78 | public void setSurfaceTexture(SurfaceTexture surfaceTexture) {
79 | if (mSurfaceTexture == surfaceTexture)
80 | return;
81 |
82 | releaseSurfaceTexture();
83 | mSurfaceTexture = surfaceTexture;
84 | if (surfaceTexture == null) {
85 | super.setSurface(null);
86 | } else {
87 | super.setSurface(new Surface(surfaceTexture));
88 | }
89 | }
90 |
91 | @Override
92 | public SurfaceTexture getSurfaceTexture() {
93 | return mSurfaceTexture;
94 | }
95 |
96 | @Override
97 | public void setSurfaceTextureHost(ISurfaceTextureHost surfaceTextureHost) {
98 | mSurfaceTextureHost = surfaceTextureHost;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/annotations/AccessedByNative.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013-2014 Bilibili
3 | * Copyright (C) 2013-2014 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.annotations;
19 |
20 | import java.lang.annotation.ElementType;
21 | import java.lang.annotation.Retention;
22 | import java.lang.annotation.RetentionPolicy;
23 | import java.lang.annotation.Target;
24 |
25 | /**
26 | * is used by the JNI generator to create the necessary JNI
27 | * bindings and expose this method to native code.
28 | */
29 | @Target(ElementType.FIELD)
30 | @Retention(RetentionPolicy.CLASS)
31 | public @interface AccessedByNative {
32 | }
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/annotations/CalledByNative.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013-2014 Bilibili
3 | * Copyright (C) 2013-2014 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.annotations;
19 |
20 | import java.lang.annotation.ElementType;
21 | import java.lang.annotation.Retention;
22 | import java.lang.annotation.RetentionPolicy;
23 | import java.lang.annotation.Target;
24 |
25 | /**
26 | * is used by the JNI generator to create the necessary JNI
27 | * bindings and expose this method to native code.
28 | */
29 | @Target(ElementType.METHOD)
30 | @Retention(RetentionPolicy.CLASS)
31 | public @interface CalledByNative {
32 | /*
33 | * If present, tells which inner class the method belongs to.
34 | */
35 | String value() default "";
36 | }
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/exceptions/IjkMediaException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013-2014 Bilibili
3 | * Copyright (C) 2013-2014 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.exceptions;
19 |
20 | public class IjkMediaException extends Exception {
21 | private static final long serialVersionUID = 7234796519009099506L;
22 | }
23 |
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/ffmpeg/FFmpegApi.java:
--------------------------------------------------------------------------------
1 | package tv.danmaku.ijk.media.player.ffmpeg;
2 |
3 | public class FFmpegApi {
4 | public static native String av_base64_encode(byte in[]);
5 | }
6 |
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/misc/AndroidMediaFormat.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Bilibili
3 | * Copyright (C) 2015 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.misc;
19 |
20 | import android.annotation.TargetApi;
21 | import android.media.MediaFormat;
22 | import android.os.Build;
23 |
24 | public class AndroidMediaFormat implements IMediaFormat {
25 | private final MediaFormat mMediaFormat;
26 |
27 | public AndroidMediaFormat(MediaFormat mediaFormat) {
28 | mMediaFormat = mediaFormat;
29 | }
30 |
31 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
32 | @Override
33 | public int getInteger(String name) {
34 | if (mMediaFormat == null)
35 | return 0;
36 |
37 | return mMediaFormat.getInteger(name);
38 | }
39 |
40 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
41 | @Override
42 | public String getString(String name) {
43 | if (mMediaFormat == null)
44 | return null;
45 |
46 | return mMediaFormat.getString(name);
47 | }
48 |
49 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
50 | @Override
51 | public String toString() {
52 | StringBuilder out = new StringBuilder(128);
53 | out.append(getClass().getName());
54 | out.append('{');
55 | if (mMediaFormat != null) {
56 | out.append(mMediaFormat.toString());
57 | } else {
58 | out.append("null");
59 | }
60 | out.append('}');
61 | return out.toString();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/misc/AndroidTrackInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Bilibili
3 | * Copyright (C) 2015 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.misc;
19 |
20 | import android.annotation.TargetApi;
21 | import android.media.MediaFormat;
22 | import android.media.MediaPlayer;
23 | import android.os.Build;
24 |
25 | public class AndroidTrackInfo implements ITrackInfo {
26 | private final MediaPlayer.TrackInfo mTrackInfo;
27 |
28 | public static AndroidTrackInfo[] fromMediaPlayer(MediaPlayer mp) {
29 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
30 | return fromTrackInfo(mp.getTrackInfo());
31 |
32 | return null;
33 | }
34 |
35 | private static AndroidTrackInfo[] fromTrackInfo(MediaPlayer.TrackInfo[] trackInfos) {
36 | if (trackInfos == null)
37 | return null;
38 |
39 | AndroidTrackInfo androidTrackInfo[] = new AndroidTrackInfo[trackInfos.length];
40 | for (int i = 0; i < trackInfos.length; ++i) {
41 | androidTrackInfo[i] = new AndroidTrackInfo(trackInfos[i]);
42 | }
43 |
44 | return androidTrackInfo;
45 | }
46 |
47 | private AndroidTrackInfo(MediaPlayer.TrackInfo trackInfo) {
48 | mTrackInfo = trackInfo;
49 | }
50 |
51 | @TargetApi(Build.VERSION_CODES.KITKAT)
52 | @Override
53 | public IMediaFormat getFormat() {
54 | if (mTrackInfo == null)
55 | return null;
56 |
57 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
58 | return null;
59 |
60 | MediaFormat mediaFormat = mTrackInfo.getFormat();
61 | if (mediaFormat == null)
62 | return null;
63 |
64 | return new AndroidMediaFormat(mediaFormat);
65 | }
66 |
67 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
68 | @Override
69 | public String getLanguage() {
70 | if (mTrackInfo == null)
71 | return "und";
72 |
73 | return mTrackInfo.getLanguage();
74 | }
75 |
76 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
77 | @Override
78 | public int getTrackType() {
79 | if (mTrackInfo == null)
80 | return MEDIA_TRACK_TYPE_UNKNOWN;
81 |
82 | return mTrackInfo.getTrackType();
83 | }
84 |
85 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
86 | @Override
87 | public String toString() {
88 | StringBuilder out = new StringBuilder(128);
89 | out.append(getClass().getSimpleName());
90 | out.append('{');
91 | if (mTrackInfo != null) {
92 | out.append(mTrackInfo.toString());
93 | } else {
94 | out.append("null");
95 | }
96 | out.append('}');
97 | return out.toString();
98 | }
99 |
100 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
101 | @Override
102 | public String getInfoInline() {
103 | if (mTrackInfo != null) {
104 | return mTrackInfo.toString();
105 | } else {
106 | return "null";
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/misc/IAndroidIO.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2016 Bilibili
3 | * Copyright (C) 2016 Raymond Zheng
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.misc;
19 |
20 | import java.io.IOException;
21 |
22 | @SuppressWarnings("RedundantThrows")
23 | public interface IAndroidIO {
24 | int open(String url) throws IOException;
25 | int read(byte[] buffer, int size) throws IOException;
26 | long seek(long offset, int whence) throws IOException;
27 | int close() throws IOException;
28 | }
29 |
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/misc/IMediaDataSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Bilibili
3 | * Copyright (C) 2015 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.misc;
19 |
20 | import java.io.IOException;
21 |
22 | @SuppressWarnings("RedundantThrows")
23 | public interface IMediaDataSource {
24 | int readAt(long position, byte[] buffer, int offset, int size) throws IOException;
25 |
26 | long getSize() throws IOException;
27 |
28 | void close() throws IOException;
29 | }
30 |
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/misc/IMediaFormat.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Bilibili
3 | * Copyright (C) 2015 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.misc;
19 |
20 | public interface IMediaFormat {
21 | // Common keys
22 | String KEY_MIME = "mime";
23 |
24 | // Video Keys
25 | String KEY_WIDTH = "width";
26 | String KEY_HEIGHT = "height";
27 |
28 | String getString(String name);
29 |
30 | int getInteger(String name);
31 | }
32 |
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/misc/ITrackInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Bilibili
3 | * Copyright (C) 2015 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.misc;
19 |
20 | public interface ITrackInfo {
21 | int MEDIA_TRACK_TYPE_AUDIO = 2;
22 | int MEDIA_TRACK_TYPE_METADATA = 5;
23 | int MEDIA_TRACK_TYPE_SUBTITLE = 4;
24 | int MEDIA_TRACK_TYPE_TIMEDTEXT = 3;
25 | int MEDIA_TRACK_TYPE_UNKNOWN = 0;
26 | int MEDIA_TRACK_TYPE_VIDEO = 1;
27 |
28 | IMediaFormat getFormat();
29 |
30 | String getLanguage();
31 |
32 | int getTrackType();
33 |
34 | String getInfoInline();
35 | }
36 |
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/misc/IjkTrackInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Bilibili
3 | * Copyright (C) 2015 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.misc;
19 |
20 | import android.text.TextUtils;
21 |
22 | import tv.danmaku.ijk.media.player.IjkMediaMeta;
23 |
24 | public class IjkTrackInfo implements ITrackInfo {
25 | private int mTrackType = MEDIA_TRACK_TYPE_UNKNOWN;
26 | private IjkMediaMeta.IjkStreamMeta mStreamMeta;
27 |
28 | public IjkTrackInfo(IjkMediaMeta.IjkStreamMeta streamMeta) {
29 | mStreamMeta = streamMeta;
30 | }
31 |
32 | public void setMediaMeta(IjkMediaMeta.IjkStreamMeta streamMeta) {
33 | mStreamMeta = streamMeta;
34 | }
35 |
36 | @Override
37 | public IMediaFormat getFormat() {
38 | return new IjkMediaFormat(mStreamMeta);
39 | }
40 |
41 | @Override
42 | public String getLanguage() {
43 | if (mStreamMeta == null || TextUtils.isEmpty(mStreamMeta.mLanguage))
44 | return "und";
45 |
46 | return mStreamMeta.mLanguage;
47 | }
48 |
49 | @Override
50 | public int getTrackType() {
51 | return mTrackType;
52 | }
53 |
54 | public void setTrackType(int trackType) {
55 | mTrackType = trackType;
56 | }
57 |
58 | @Override
59 | public String toString() {
60 | return getClass().getSimpleName() + '{' + getInfoInline() + "}";
61 | }
62 |
63 | @Override
64 | public String getInfoInline() {
65 | StringBuilder out = new StringBuilder(128);
66 | switch (mTrackType) {
67 | case MEDIA_TRACK_TYPE_VIDEO:
68 | out.append("VIDEO");
69 | out.append(", ");
70 | out.append(mStreamMeta.getCodecShortNameInline());
71 | out.append(", ");
72 | out.append(mStreamMeta.getBitrateInline());
73 | out.append(", ");
74 | out.append(mStreamMeta.getResolutionInline());
75 | break;
76 | case MEDIA_TRACK_TYPE_AUDIO:
77 | out.append("AUDIO");
78 | out.append(", ");
79 | out.append(mStreamMeta.getCodecShortNameInline());
80 | out.append(", ");
81 | out.append(mStreamMeta.getBitrateInline());
82 | out.append(", ");
83 | out.append(mStreamMeta.getSampleRateInline());
84 | break;
85 | case MEDIA_TRACK_TYPE_TIMEDTEXT:
86 | out.append("TIMEDTEXT");
87 | out.append(", ");
88 | out.append(mStreamMeta.mLanguage);
89 | break;
90 | case MEDIA_TRACK_TYPE_SUBTITLE:
91 | out.append("SUBTITLE");
92 | break;
93 | default:
94 | out.append("UNKNOWN");
95 | break;
96 | }
97 | return out.toString();
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/pragma/DebugLog.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Bilibili
3 | * Copyright (C) 2013 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package tv.danmaku.ijk.media.player.pragma;
19 |
20 | import java.util.Locale;
21 |
22 |
23 | import android.util.Log;
24 |
25 | @SuppressWarnings({"SameParameterValue", "WeakerAccess"})
26 | public class DebugLog {
27 | public static final boolean ENABLE_ERROR = Pragma.ENABLE_VERBOSE;
28 | public static final boolean ENABLE_INFO = Pragma.ENABLE_VERBOSE;
29 | public static final boolean ENABLE_WARN = Pragma.ENABLE_VERBOSE;
30 | public static final boolean ENABLE_DEBUG = Pragma.ENABLE_VERBOSE;
31 | public static final boolean ENABLE_VERBOSE = Pragma.ENABLE_VERBOSE;
32 |
33 | public static void e(String tag, String msg) {
34 | if (ENABLE_ERROR) {
35 | Log.e(tag, msg);
36 | }
37 | }
38 |
39 | public static void e(String tag, String msg, Throwable tr) {
40 | if (ENABLE_ERROR) {
41 | Log.e(tag, msg, tr);
42 | }
43 | }
44 |
45 | public static void efmt(String tag, String fmt, Object... args) {
46 | if (ENABLE_ERROR) {
47 | String msg = String.format(Locale.US, fmt, args);
48 | Log.e(tag, msg);
49 | }
50 | }
51 |
52 | public static void i(String tag, String msg) {
53 | if (ENABLE_INFO) {
54 | Log.i(tag, msg);
55 | }
56 | }
57 |
58 | public static void i(String tag, String msg, Throwable tr) {
59 | if (ENABLE_INFO) {
60 | Log.i(tag, msg, tr);
61 | }
62 | }
63 |
64 | public static void ifmt(String tag, String fmt, Object... args) {
65 | if (ENABLE_INFO) {
66 | String msg = String.format(Locale.US, fmt, args);
67 | Log.i(tag, msg);
68 | }
69 | }
70 |
71 | public static void w(String tag, String msg) {
72 | if (ENABLE_WARN) {
73 | Log.w(tag, msg);
74 | }
75 | }
76 |
77 | public static void w(String tag, String msg, Throwable tr) {
78 | if (ENABLE_WARN) {
79 | Log.w(tag, msg, tr);
80 | }
81 | }
82 |
83 | public static void wfmt(String tag, String fmt, Object... args) {
84 | if (ENABLE_WARN) {
85 | String msg = String.format(Locale.US, fmt, args);
86 | Log.w(tag, msg);
87 | }
88 | }
89 |
90 | public static void d(String tag, String msg) {
91 | if (ENABLE_DEBUG) {
92 | Log.d(tag, msg);
93 | }
94 | }
95 |
96 | public static void d(String tag, String msg, Throwable tr) {
97 | if (ENABLE_DEBUG) {
98 | Log.d(tag, msg, tr);
99 | }
100 | }
101 |
102 | public static void dfmt(String tag, String fmt, Object... args) {
103 | if (ENABLE_DEBUG) {
104 | String msg = String.format(Locale.US, fmt, args);
105 | Log.d(tag, msg);
106 | }
107 | }
108 |
109 | public static void v(String tag, String msg) {
110 | if (ENABLE_VERBOSE) {
111 | Log.v(tag, msg);
112 | }
113 | }
114 |
115 | public static void v(String tag, String msg, Throwable tr) {
116 | if (ENABLE_VERBOSE) {
117 | Log.v(tag, msg, tr);
118 | }
119 | }
120 |
121 | public static void vfmt(String tag, String fmt, Object... args) {
122 | if (ENABLE_VERBOSE) {
123 | String msg = String.format(Locale.US, fmt, args);
124 | Log.v(tag, msg);
125 | }
126 | }
127 |
128 | public static void printStackTrace(Throwable e) {
129 | if (ENABLE_WARN) {
130 | e.printStackTrace();
131 | }
132 | }
133 |
134 | public static void printCause(Throwable e) {
135 | if (ENABLE_WARN) {
136 | Throwable cause = e.getCause();
137 | if (cause != null)
138 | e = cause;
139 |
140 | printStackTrace(e);
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/android/src/main/java/tv/danmaku/ijk/media/player/pragma/Pragma.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Bilibili
3 | * Copyright (C) 2013 Zhang Rui
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package tv.danmaku.ijk.media.player.pragma;
18 |
19 | /*-
20 | * configurated by app project
21 | */
22 | public class Pragma {
23 | public static final boolean ENABLE_VERBOSE = true;
24 | }
25 |
--------------------------------------------------------------------------------
/android/src/main/libs/arm64-v8a/libijkffmpeg.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/android/src/main/libs/arm64-v8a/libijkffmpeg.so
--------------------------------------------------------------------------------
/android/src/main/libs/arm64-v8a/libijkplayer.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/android/src/main/libs/arm64-v8a/libijkplayer.so
--------------------------------------------------------------------------------
/android/src/main/libs/arm64-v8a/libijksdl.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/android/src/main/libs/arm64-v8a/libijksdl.so
--------------------------------------------------------------------------------
/android/src/main/libs/armeabi-v7a/libijkffmpeg.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/android/src/main/libs/armeabi-v7a/libijkffmpeg.so
--------------------------------------------------------------------------------
/android/src/main/libs/armeabi-v7a/libijkplayer.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/android/src/main/libs/armeabi-v7a/libijkplayer.so
--------------------------------------------------------------------------------
/android/src/main/libs/armeabi-v7a/libijksdl.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/android/src/main/libs/armeabi-v7a/libijksdl.so
--------------------------------------------------------------------------------
/android/src/main/libs/x86/libijkffmpeg.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/android/src/main/libs/x86/libijkffmpeg.so
--------------------------------------------------------------------------------
/android/src/main/libs/x86/libijkplayer.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/android/src/main/libs/x86/libijkplayer.so
--------------------------------------------------------------------------------
/android/src/main/libs/x86/libijksdl.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/android/src/main/libs/x86/libijksdl.so
--------------------------------------------------------------------------------
/android/src/main/libs/x86_64/libijkffmpeg.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/android/src/main/libs/x86_64/libijkffmpeg.so
--------------------------------------------------------------------------------
/android/src/main/libs/x86_64/libijkplayer.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/android/src/main/libs/x86_64/libijkplayer.so
--------------------------------------------------------------------------------
/android/src/main/libs/x86_64/libijksdl.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/android/src/main/libs/x86_64/libijksdl.so
--------------------------------------------------------------------------------
/android/switch_env.sh:
--------------------------------------------------------------------------------
1 | cd src/main
2 | case "$1" in
3 | "dev")
4 | mv libs libs-prod
5 | ln -s /Volumes/Samsung-T5/code/media_projects/ijkplayer/flutter_ijk/android/out/libs libs
6 | ;;
7 | "prod")
8 | rm libs
9 | mv libs-prod libs
10 | ;;
11 | *)
12 | echo "$0 dev|prod"
13 | exit 1
14 | ;;
15 | esac
16 |
--------------------------------------------------------------------------------
/example/.flutter-plugins-dependencies:
--------------------------------------------------------------------------------
1 | {"_info":"// This is a generated file; do not edit or check into version control.","dependencyGraph":[{"name":"flutter_ijkplayer","dependencies":[]},{"name":"photo_manager","dependencies":[]}]}
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # Visual Studio Code related
19 | .vscode/
20 |
21 | # Flutter/Dart/Pub related
22 | **/doc/api/
23 | .dart_tool/
24 | .flutter-plugins
25 | .packages
26 | .pub-cache/
27 | .pub/
28 | /build/
29 |
30 | # Android related
31 | **/android/**/gradle-wrapper.jar
32 | **/android/.gradle
33 | **/android/captures/
34 | **/android/gradlew
35 | **/android/gradlew.bat
36 | **/android/local.properties
37 | **/android/**/GeneratedPluginRegistrant.java
38 |
39 | # iOS/XCode related
40 | **/ios/**/*.mode1v3
41 | **/ios/**/*.mode2v3
42 | **/ios/**/*.moved-aside
43 | **/ios/**/*.pbxuser
44 | **/ios/**/*.perspectivev3
45 | **/ios/**/*sync/
46 | **/ios/**/.sconsign.dblite
47 | **/ios/**/.tags*
48 | **/ios/**/.vagrant/
49 | **/ios/**/DerivedData/
50 | **/ios/**/Icon?
51 | **/ios/**/Pods/
52 | **/ios/**/.symlinks/
53 | **/ios/**/profile
54 | **/ios/**/xcuserdata
55 | **/ios/.generated/
56 | **/ios/Flutter/App.framework
57 | **/ios/Flutter/Flutter.framework
58 | **/ios/Flutter/Generated.xcconfig
59 | **/ios/Flutter/app.flx
60 | **/ios/Flutter/app.zip
61 | **/ios/Flutter/flutter_assets/
62 | **/ios/ServiceDefinitions.json
63 | **/ios/Runner/GeneratedPluginRegistrant.*
64 |
65 | # Exceptions to above rules.
66 | !**/ios/**/default.mode1v3
67 | !**/ios/**/default.mode2v3
68 | !**/ios/**/default.pbxuser
69 | !**/ios/**/default.perspectivev3
70 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
71 |
--------------------------------------------------------------------------------
/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: 7fc14a55af64462763d28abfb4e610086c6e0f39
8 | channel: dev
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 | This project is a starting point for a Flutter application.
8 |
9 | A few resources to get you started if this is your first Flutter project:
10 |
11 | - [Lab: Write your first Flutter app](https://flutter.io/docs/get-started/codelab)
12 | - [Cookbook: Useful Flutter samples](https://flutter.io/docs/cookbook)
13 |
14 | For help getting started with Flutter, view our
15 | [online documentation](https://flutter.io/docs), which offers tutorials,
16 | samples, guidance on mobile development, and a full API reference.
17 |
--------------------------------------------------------------------------------
/example/android/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | android
4 | Project android created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.buildship.core.gradleprojectbuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.buildship.core.gradleprojectnature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/example/android/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | connection.project.dir=
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/example/android/app/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/example/android/app/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | app
4 | Project app created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.buildship.core.gradleprojectbuilder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.jdt.core.javanature
21 | org.eclipse.buildship.core.gradleprojectnature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/example/android/app/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | connection.project.dir=..
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/example/android/app/arm64.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: Arm64Plugin
2 |
3 | class Arm64Plugin implements Plugin {
4 | private Properties localProperties
5 |
6 | private Properties readPropertiesIfExist(File propertiesFile) {
7 | Properties result = new Properties()
8 | if (propertiesFile.exists()) {
9 | propertiesFile.withReader('UTF-8') { reader -> result.load(reader) }
10 | }
11 | return result
12 | }
13 |
14 | private String resolveProperty(Project project, String name, String defaultValue) {
15 | if (localProperties == null) {
16 | localProperties = readPropertiesIfExist(new File(project.projectDir.parentFile, "local.properties"))
17 | }
18 | String result
19 | if (project.hasProperty(name)) {
20 | result = project.property(name)
21 | }
22 | if (result == null) {
23 | result = localProperties.getProperty(name)
24 | }
25 | if (result == null) {
26 | result = defaultValue
27 | }
28 | return result
29 | }
30 |
31 | @Override
32 | void apply(Project project) {
33 | project.android.buildTypes {
34 | profile {
35 | initWith debug
36 | if (it.hasProperty('matchingFallbacks')) {
37 | matchingFallbacks = ['debug', 'release']
38 | }
39 | }
40 | dynamicProfile {
41 | initWith debug
42 | if (it.hasProperty('matchingFallbacks')) {
43 | matchingFallbacks = ['debug', 'release']
44 | }
45 | }
46 | dynamicRelease {
47 | initWith debug
48 | if (it.hasProperty('matchingFallbacks')) {
49 | matchingFallbacks = ['debug', 'release']
50 | }
51 | }
52 | }
53 |
54 | String flutterRoot = resolveProperty(project, "flutter.sdk", System.env.FLUTTER_ROOT)
55 | // 原始jar包文件
56 | def zipFile = file("$flutterRoot/bin/cache/artifacts/engine/android-arm64-dynamic-release/flutter.jar")
57 |
58 | // 解压缩目标目录
59 | def outputDir = file("$flutterRoot/bin/cache/artifacts/engine/android-arm64-dynamic-release/dist")
60 |
61 | // FileTree jarTree = zipTree(zipFile)
62 | //
63 | // from jarTree
64 | // into outputDir
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/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 | android {
27 | signingConfigs {
28 | config1 {
29 | keyAlias 'run'
30 | keyPassword '123456'
31 | storeFile file("${project.rootDir}/example-key.jks")
32 | storePassword '123456'
33 | }
34 | }
35 | compileSdkVersion 29
36 | lintOptions {
37 | disable 'InvalidPackage'
38 | }
39 | defaultConfig {
40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
41 | applicationId "com.example.ijkplayer_example"
42 | minSdkVersion 16
43 | targetSdkVersion 28
44 | versionCode flutterVersionCode.toInteger()
45 | versionName flutterVersionName
46 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
47 |
48 | }
49 | buildTypes {
50 | release {
51 | // TODO: Add your own signing config for the release build.
52 | // Signing with the debug keys for now, so `flutter run --release` works.
53 | signingConfig signingConfigs.config1
54 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'app/proguard-rules.pro'
55 | }
56 | debug {
57 | signingConfig signingConfigs.config1
58 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'app/proguard-rules.pro'
59 | }
60 | }
61 | }
62 |
63 | flutter {
64 | source '../..'
65 | }
66 |
67 | dependencies {
68 | // testImplementation 'junit:junit:4.12'
69 | // androidTestImplementation 'com.android.support.test:runner:1.0.2'
70 | // androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
71 | }
72 |
--------------------------------------------------------------------------------
/example/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/example/android/app/proguard-rules.pro
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
9 |
13 |
20 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/example/ijkplayer_example/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.ijkplayer_example;
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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.21'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.3.2'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | jcenter()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 |
23 | subprojects {
24 | project.buildDir = "${rootProject.buildDir}/${project.name}"
25 | project.evaluationDependsOn(':app')
26 | }
27 |
28 | task clean(type: Delete) {
29 | delete rootProject.buildDir
30 | }
31 |
--------------------------------------------------------------------------------
/example/android/example-key.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/example/android/example-key.jks
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | #target-platform=android-arm
3 | android.enableJetifier=true
4 | android.useAndroidX=true
5 | android.enableR8=true
6 |
--------------------------------------------------------------------------------
/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=https\://services.gradle.org/distributions/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/assets/sample1.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/example/assets/sample1.mp4
--------------------------------------------------------------------------------
/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/Flutter.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # NOTE: This podspec is NOT to be published. It is only used as a local source!
3 | #
4 |
5 | Pod::Spec.new do |s|
6 | s.name = 'Flutter'
7 | s.version = '1.0.0'
8 | s.summary = 'High-performance, high-fidelity mobile apps.'
9 | s.description = <<-DESC
10 | Flutter provides an easy and productive way to build and deploy high-performance mobile apps for Android and iOS.
11 | DESC
12 | s.homepage = 'https://flutter.io'
13 | s.license = { :type => 'MIT' }
14 | s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
15 | s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
16 | s.ios.deployment_target = '8.0'
17 | s.vendored_frameworks = 'Flutter.framework'
18 | end
19 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/ios/Flutter/flutter_export_environment.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # This is a generated file; do not edit or check into version control.
3 | export "FLUTTER_ROOT=/Users/caijinglong/Library/Flutter/flutter_dev"
4 | export "FLUTTER_APPLICATION_PATH=/Volumes/Samsung-T5/code/flutter/plugins/flutter_ijkplayer/example"
5 | export "FLUTTER_TARGET=/Volumes/Samsung-T5/code/flutter/plugins/flutter_ijkplayer/example/lib/main.dart"
6 | export "FLUTTER_BUILD_DIR=build"
7 | export "SYMROOT=${SOURCE_ROOT}/../build/ios"
8 | export "FLUTTER_FRAMEWORK_DIR=/Users/caijinglong/Library/Flutter/flutter_dev/bin/cache/artifacts/engine/ios"
9 | export "FLUTTER_BUILD_NAME=1.0.0"
10 | export "FLUTTER_BUILD_NUMBER=1"
11 | export "TRACK_WIDGET_CREATION=true"
12 |
--------------------------------------------------------------------------------
/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 | generated_key_values = {}
19 | skip_line_start_symbols = ["#", "/"]
20 | File.foreach(file_abs_path) do |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 | generated_key_values[podname] = podpath
28 | else
29 | puts "Invalid plugin specification: #{line}"
30 | end
31 | end
32 | generated_key_values
33 | end
34 |
35 | target 'Runner' do
36 | # Flutter Pod
37 |
38 | copied_flutter_dir = File.join(__dir__, 'Flutter')
39 | copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
40 | copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
41 | unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
42 | # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
43 | # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
44 | # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
45 |
46 | generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
47 | unless File.exist?(generated_xcode_build_settings_path)
48 | raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
49 | end
50 | generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
51 | cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
52 |
53 | unless File.exist?(copied_framework_path)
54 | FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
55 | end
56 | unless File.exist?(copied_podspec_path)
57 | FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
58 | end
59 | end
60 |
61 | # Keep pod path relative so it can be checked into Podfile.lock.
62 | pod 'Flutter', :path => 'Flutter'
63 |
64 | # Plugin Pods
65 |
66 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
67 | # referring to absolute paths on developers' machines.
68 | system('rm -rf .symlinks')
69 | system('mkdir -p .symlinks/plugins')
70 | plugin_pods = parse_KV_file('../.flutter-plugins')
71 | plugin_pods.each do |name, path|
72 | specPath = "#{path}/ios/#{name}.podspec"
73 | pod name,:path=>specPath
74 | end
75 | end
76 |
77 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
78 | install! 'cocoapods', :disable_input_output_paths => true
79 |
80 | post_install do |installer|
81 | installer.pods_project.targets.each do |target|
82 | target.build_configurations.each do |config|
83 | config.build_settings['ENABLE_BITCODE'] = 'NO'
84 | end
85 | end
86 | end
87 |
--------------------------------------------------------------------------------
/example/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Flutter (1.0.0)
3 | - flutter_ijkplayer (0.0.1):
4 | - Flutter
5 | - FlutterIJK (~> 0.2.3)
6 | - FlutterIJK (0.2.3)
7 | - photo_manager (0.0.1):
8 | - Flutter
9 |
10 | DEPENDENCIES:
11 | - Flutter (from `Flutter`)
12 | - flutter_ijkplayer (from `/Volumes/Samsung-T5/code/flutter/plugins/flutter_ijkplayer/ios/flutter_ijkplayer.podspec`)
13 | - photo_manager (from `/Users/caijinglong/.pub-cache/git/flutter_photo_manager-15e4b37a4b3efc07b7500f94d316dfe02f1a324a/ios/photo_manager.podspec`)
14 |
15 | SPEC REPOS:
16 | trunk:
17 | - FlutterIJK
18 |
19 | EXTERNAL SOURCES:
20 | Flutter:
21 | :path: Flutter
22 | flutter_ijkplayer:
23 | :path: "/Volumes/Samsung-T5/code/flutter/plugins/flutter_ijkplayer/ios/flutter_ijkplayer.podspec"
24 | photo_manager:
25 | :path: "/Users/caijinglong/.pub-cache/git/flutter_photo_manager-15e4b37a4b3efc07b7500f94d316dfe02f1a324a/ios/photo_manager.podspec"
26 |
27 | SPEC CHECKSUMS:
28 | Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
29 | flutter_ijkplayer: a8f1ef22fa3e22e1ea80b70e6cb70b049cf88063
30 | FlutterIJK: f3715f94cea893b0e643b2b27b781033a1bb5007
31 | photo_manager: f7c619c2cc8c2adb8d85c63363babac477de9c67
32 |
33 | PODFILE CHECKSUM: 806836eca77383388df20b27737ff664222206cd
34 |
35 | COCOAPODS: 1.9.1
36 |
--------------------------------------------------------------------------------
/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/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
69 |
71 |
77 |
78 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/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 | top.kikt.ijkplayer.example
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | flutter_IjkPlayer_example
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(MARKETING_VERSION)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0.0
23 | LSRequiresIPhoneOS
24 |
25 | NSPhotoLibraryUsageDescription
26 | App need your agree, can visit your album
27 | UIBackgroundModes
28 |
29 | fetch
30 | remote-notification
31 |
32 | UILaunchStoryboardName
33 | LaunchScreen
34 | UIMainStoryboardFile
35 | Main
36 | UISupportedInterfaceOrientations
37 |
38 | UIInterfaceOrientationPortrait
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UISupportedInterfaceOrientations~ipad
43 |
44 | UIInterfaceOrientationPortrait
45 | UIInterfaceOrientationPortraitUpsideDown
46 | UIInterfaceOrientationLandscapeLeft
47 | UIInterfaceOrientationLandscapeRight
48 |
49 | UIViewControllerBasedStatusBarAppearance
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/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/const/resource.dart:
--------------------------------------------------------------------------------
1 | /// generate by resouce_generator library, shouldn't edit.
2 | class R {
3 | /// 
4 | static const String ASSETS_SAMPLE1_MP4 = "assets/sample1.mp4";
5 | }
6 |
--------------------------------------------------------------------------------
/example/lib/const/video_datasource.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
2 |
3 | class VideoDataSource {
4 | static final springBootMenuM3u8 = DataSource.network(
5 | "https://media001.geekbang.org/f433fd1ce5e84d27b1101f0dad72a126/de563bb4aba94b5f95f448b33be4dd9f-9aede6861be944d696fe365f3a33b7b4-sd.m3u8");
6 |
7 | static final ai = DataSource.network(
8 | "http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4");
9 |
10 | static final reportErrorM3u8FromAliyun = DataSource.network(
11 | "https://outin-4839d24d670f11e988c600163e1a3b4a.oss-cn-shanghai.aliyuncs.com/2b9f4f2d1c4d4985a11352cb1970fead/86c3f36ed4e1cd5539ed347282725b3e-fd-encrypt-stream.m3u8?Expires=1563162783&OSSAccessKeyId=LTAIrkwb21KyGjJl&Signature=y4m98BAzJUQVzFwHszQS%2BFGtq5A%3D");
12 | }
13 |
--------------------------------------------------------------------------------
/example/lib/i18n/cn.dart:
--------------------------------------------------------------------------------
1 | part of 'i18n.dart';
2 |
3 | class _I18nZh extends I18n {
4 | _I18nZh() : super._();
5 |
6 | @override
7 | String get indexTitle => "首页";
8 |
9 | @override
10 | String get assetButton => "播放asset视频";
11 |
12 | @override
13 | String get fullScreenAutoButton => "全屏切换示例(自动)";
14 |
15 | @override
16 | String get fullScreenManualButton => "全屏切换示例(手动)";
17 |
18 | @override
19 | String get listViewButton => "在ListView中";
20 |
21 | @override
22 | String get networkButton => "播放网络视频";
23 |
24 | @override
25 | String get pageViewButton => "在PageView中播放视频";
26 |
27 | @override
28 | String get photoButton => "在相册中播放";
29 |
30 | @override
31 | String get withDialogButton => "在dialog中播放";
32 |
33 | @override
34 | String get showDialog => "显示 dialog";
35 |
36 | @override
37 | String get autoFullScreenTitle => "切换横竖屏可以看到界面变化";
38 |
39 | @override
40 | String get changeFullScreenWithButton => "点击按钮切换横竖屏";
41 |
42 | @override
43 | String get fullScreen => "全屏";
44 |
45 | @override
46 | String get play => "播放";
47 |
48 | @override
49 | String get noPickTip => "没有选择";
50 |
51 | @override
52 | String get pick => "选择";
53 |
54 | @override
55 | String get useStreamUsage => "Controller stream的使用";
56 |
57 | @override
58 | String get playFinishToast => "播放完毕";
59 |
60 | @override
61 | String get screenshotTitle => "截取视频画面";
62 |
63 | @override
64 | String get overlayPageTitle => "悬浮窗中显示(开发中)";
65 |
66 | @override
67 | String get ijkStatusTitle => "IjkStatus的使用";
68 |
69 | @override
70 | String get customOption => "自定义Option的使用";
71 |
72 | @override
73 | String get errorUrl => "错误的url";
74 |
75 | @override
76 | String get customFullScreenWidget => "自定义全屏界面";
77 |
78 | @override
79 | String get setSpeed => "播放速度";
80 |
81 | @override
82 | String get autoFullScreenOnPlay => "在开始播放时自动播放";
83 | }
84 |
--------------------------------------------------------------------------------
/example/lib/i18n/en.dart:
--------------------------------------------------------------------------------
1 | part of 'i18n.dart';
2 |
3 | class _I18nEn extends I18n {
4 | _I18nEn() : super._();
5 |
6 | @override
7 | String get indexTitle => "index";
8 |
9 | @override
10 | String get assetButton => "Play asset video";
11 |
12 | @override
13 | String get fullScreenAutoButton => "Full Screen (Auto)";
14 |
15 | @override
16 | String get fullScreenManualButton => "Full Screen (Manual)";
17 |
18 | @override
19 | String get listViewButton => "Use in ListView";
20 |
21 | @override
22 | String get networkButton => "Play network video";
23 |
24 | @override
25 | String get pageViewButton => "Use in PageView";
26 |
27 | @override
28 | String get photoButton => "Play video in photo";
29 |
30 | @override
31 | String get withDialogButton => "Play with dialog";
32 |
33 | @override
34 | String get showDialog => "Show dialog";
35 |
36 | @override
37 | String get autoFullScreenTitle => "Rotate device to see change";
38 |
39 | @override
40 | String get changeFullScreenWithButton => "Click button to show change";
41 |
42 | @override
43 | String get fullScreen => "full screen";
44 |
45 | @override
46 | String get play => "play";
47 |
48 | @override
49 | String get noPickTip => "at least pick one video";
50 |
51 | @override
52 | String get pick => "pick";
53 |
54 | @override
55 | String get useStreamUsage => "Controller stream usage";
56 |
57 | @override
58 | String get playFinishToast => "Play video finish";
59 |
60 | @override
61 | String get screenshotTitle => "screenshot video frame";
62 |
63 | @override
64 | String get overlayPageTitle => "In overlay(Developing)";
65 |
66 | @override
67 | String get ijkStatusTitle => "Usage of IjkStatus";
68 |
69 | @override
70 | String get customOption => "Usage of custom IjkPlayer options";
71 |
72 | @override
73 | String get errorUrl => "Error Url";
74 |
75 | @override
76 | String get customFullScreenWidget => "Custom Full Screen Interface";
77 |
78 | @override
79 | String get setSpeed => "Set media speed";
80 |
81 | @override
82 | String get autoFullScreenOnPlay => "Auto full screen on start.";
83 | }
84 |
--------------------------------------------------------------------------------
/example/lib/i18n/i18n.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 | part 'cn.dart';
3 | part 'en.dart';
4 |
5 | abstract class I18n {
6 |
7 | I18n._();
8 |
9 | factory I18n(Locale locale) {
10 | if (locale?.languageCode == "zh") {
11 | return _I18nZh();
12 | } else {
13 | return _I18nEn();
14 | }
15 | }
16 |
17 | String get indexTitle;
18 | String get networkButton;
19 | String get photoButton;
20 | String get assetButton;
21 | String get listViewButton;
22 | String get fullScreenAutoButton;
23 | String get fullScreenManualButton;
24 | String get withDialogButton;
25 | String get pageViewButton;
26 |
27 | String get showDialog;
28 |
29 | String get autoFullScreenTitle;
30 |
31 | String get changeFullScreenWithButton;
32 |
33 | String get play;
34 |
35 | String get fullScreen;
36 |
37 | String get pick;
38 |
39 | String get noPickTip;
40 |
41 | String get useStreamUsage;
42 |
43 | String get playFinishToast;
44 |
45 | String get screenshotTitle;
46 |
47 | String get overlayPageTitle;
48 |
49 | String get ijkStatusTitle;
50 |
51 | String get customOption;
52 |
53 | String get errorUrl;
54 |
55 | String get customFullScreenWidget;
56 |
57 | String get setSpeed;
58 |
59 | String get autoFullScreenOnPlay;
60 | }
61 |
62 | I18n get currentI18n => I18n(window.locale);
63 |
--------------------------------------------------------------------------------
/example/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 | import 'package:ijkplayer_example/page/index.dart';
4 | import 'package:oktoast/oktoast.dart';
5 |
6 | Future main() async {
7 | WidgetsFlutterBinding.ensureInitialized();
8 | await IjkManager.initIJKPlayer();
9 | runApp(MyApp());
10 | }
11 |
12 | class MyApp extends StatefulWidget {
13 | @override
14 | _MyAppState createState() => _MyAppState();
15 | }
16 |
17 | class _MyAppState extends State {
18 | bool isInitPlugin = false;
19 |
20 | @override
21 | void initState() {
22 | super.initState();
23 | Future.delayed(Duration.zero, () {
24 | isInitPlugin = true;
25 | setState(() {});
26 | });
27 | }
28 |
29 | @override
30 | Widget build(BuildContext context) {
31 | if (!isInitPlugin) {
32 | return Container();
33 | }
34 | return OKToast(
35 | child: MaterialApp(
36 | home: IndexPage(),
37 | ),
38 | );
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/example/lib/page/asset_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 | import 'package:ijkplayer_example/i18n/i18n.dart';
4 | import 'package:ijkplayer_example/utils/options_utils.dart';
5 |
6 | class AssetPage extends StatefulWidget {
7 | @override
8 | _AssetPageState createState() => _AssetPageState();
9 | }
10 |
11 | class _AssetPageState extends State {
12 | IjkMediaController controller = IjkMediaController();
13 |
14 | @override
15 | void initState() {
16 | super.initState();
17 | OptionUtils.addDefaultOptions(controller);
18 | }
19 |
20 | @override
21 | Widget build(BuildContext context) {
22 | return Scaffold(
23 | appBar: AppBar(
24 | title: Text(currentI18n.assetButton),
25 | ),
26 | body: ListView(
27 | children: [
28 | AspectRatio(
29 | aspectRatio: 1,
30 | child: IjkPlayer(
31 | mediaController: controller,
32 | ),
33 | )
34 | ],
35 | ),
36 | floatingActionButton: FloatingActionButton(
37 | child: Icon(Icons.play_arrow),
38 | onPressed: () async {
39 | await controller.setAssetDataSource(
40 | "assets/sample1.mp4",
41 | autoPlay: true,
42 | );
43 | await controller.pause();
44 | },
45 | ),
46 | );
47 | }
48 |
49 | @override
50 | void dispose() {
51 | controller?.dispose();
52 | super.dispose();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/example/lib/page/auto_full_screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 | import 'package:ijkplayer_example/const/video_datasource.dart';
4 | import 'package:ijkplayer_example/i18n/i18n.dart';
5 | import 'package:ijkplayer_example/utils/options_utils.dart';
6 |
7 | class AutoFullScreenPage extends StatefulWidget {
8 | @override
9 | _AutoFullScreenPageState createState() => _AutoFullScreenPageState();
10 | }
11 |
12 | class _AutoFullScreenPageState extends State {
13 | IjkMediaController controller = IjkMediaController();
14 | final key = GlobalKey();
15 |
16 | @override
17 | void initState() {
18 | super.initState();
19 | OptionUtils.addDefaultOptions(controller);
20 | setDataSource();
21 | }
22 |
23 | void setDataSource() async {
24 | await controller.setDataSource(
25 | VideoDataSource.springBootMenuM3u8,
26 | autoPlay: true,
27 | );
28 | key.currentState.fullScreen();
29 | }
30 |
31 | @override
32 | void dispose() {
33 | controller.dispose();
34 | super.dispose();
35 | }
36 |
37 | @override
38 | Widget build(BuildContext context) {
39 | return Scaffold(
40 | appBar: AppBar(
41 | title: Text(currentI18n.autoFullScreenOnPlay),
42 | ),
43 | body: Container(
44 | child: AspectRatio(
45 | aspectRatio: 1280 / 720,
46 | child: IjkPlayer(
47 | mediaController: controller,
48 | controllerWidgetBuilder: (ctl) => DefaultIJKControllerWidget(
49 | controller: ctl,
50 | key: key,
51 | ),
52 | ),
53 | ),
54 | ),
55 | );
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/example/lib/page/custom_ijk_opt_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 | import 'package:ijkplayer_example/i18n/i18n.dart';
4 |
5 | class CustomIjkOptionPage extends StatefulWidget {
6 | @override
7 | _CustomIjkOptionPageState createState() => _CustomIjkOptionPageState();
8 | }
9 |
10 | class _CustomIjkOptionPageState extends State {
11 | IjkMediaController controller = IjkMediaController();
12 |
13 | @override
14 | void initState() {
15 | super.initState();
16 | initIjkController();
17 | }
18 |
19 | @override
20 | void dispose() {
21 | controller?.dispose();
22 | super.dispose();
23 | }
24 |
25 | @override
26 | Widget build(BuildContext context) {
27 | return Scaffold(
28 | appBar: AppBar(
29 | title: Text(currentI18n.customOption),
30 | ),
31 | body: ListView(
32 | children: [
33 | AspectRatio(
34 | aspectRatio: 1280 / 720,
35 | child: IjkPlayer(
36 | mediaController: controller,
37 | ),
38 | ),
39 | ],
40 | ),
41 | );
42 | }
43 |
44 | void initIjkController() async {
45 | var option1 = IjkOption(IjkOptionCategory.format, "fflags", "fastseek");
46 |
47 | controller.setIjkPlayerOptions(
48 | [TargetPlatform.iOS, TargetPlatform.android],
49 | [option1].toSet(),
50 | );
51 |
52 | await controller.setDataSource(
53 | DataSource.network(
54 | "http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4"),
55 | autoPlay: true,
56 | );
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/example/lib/page/developing/crash_on_set_src_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 |
4 | class CrashOnSetSrcPage extends StatefulWidget {
5 | @override
6 | _CrashOnSetSrcPageState createState() => _CrashOnSetSrcPageState();
7 | }
8 |
9 | class _CrashOnSetSrcPageState extends State {
10 | IjkMediaController controller;
11 |
12 | List networkList = [
13 | "http://playertest.longtailvideo.com/adaptive/bipbop/gear4/prog_index.m3u8",
14 | "http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4",
15 | "https://media001.geekbang.org/f433fd1ce5e84d27b1101f0dad72a126/de563bb4aba94b5f95f448b33be4dd9f-9aede6861be944d696fe365f3a33b7b4-sd.m3u8",
16 | ];
17 |
18 | int currentIndex = 0;
19 |
20 | @override
21 | void initState() {
22 | super.initState();
23 | controller = IjkMediaController();
24 | }
25 |
26 | @override
27 | void dispose() {
28 | controller.dispose();
29 | super.dispose();
30 | }
31 |
32 | @override
33 | Widget build(BuildContext context) {
34 | return Scaffold(
35 | appBar: AppBar(
36 | title: Text("切换数据崩溃"),
37 | ),
38 | body: ListView(
39 | children: [
40 | AspectRatio(
41 | aspectRatio: 1,
42 | child: IjkPlayer(
43 | mediaController: controller,
44 | ),
45 | ),
46 | ],
47 | ),
48 | floatingActionButton: FloatingActionButton(
49 | onPressed: () {
50 | final url = networkList[currentIndex];
51 | controller.setDataSource(DataSource.network(url), autoPlay: true);
52 | currentIndex++;
53 | currentIndex %= networkList.length;
54 | },
55 | ),
56 | );
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/example/lib/page/developing/develop_index.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:ijkplayer_example/page/developing/test_hide_system_bar.dart';
3 |
4 | import 'crash_on_set_src_page.dart';
5 | import 'develop_prepare_page.dart';
6 | import 'live_interruption_page.dart';
7 | import 'new_full_screen_page.dart';
8 | import 'src_error_page.dart';
9 |
10 | class DevelopingIndexPage extends StatefulWidget {
11 | @override
12 | DevelopingIndexPageState createState() => DevelopingIndexPageState();
13 | }
14 |
15 | class DevelopingIndexPageState extends State {
16 | @override
17 | Widget build(BuildContext context) {
18 | return Scaffold(
19 | appBar: AppBar(
20 | title: Text("For Developer , user don't use."),
21 | ),
22 | body: ListView(
23 | children: [
24 | buildButton("developing preare page", ForPreparePage()),
25 | buildButton("切换视频源crash", CrashOnSetSrcPage()),
26 | buildButton("直播中断", LiveInterruptionPage()),
27 | buildButton("视频源错误", SreErrorPage()),
28 | buildButton("新的全屏", NewFullScreenPage()),
29 | buildButton("隐藏或显示状态栏", TestHideSystemBar()),
30 | ],
31 | ),
32 | );
33 | }
34 |
35 | Widget buildButton(String text, Widget targetPage) {
36 | return FlatButton(
37 | onPressed: () {
38 | Navigator.push(context, MaterialPageRoute(builder: (_) => targetPage));
39 | },
40 | child: Text(text),
41 | );
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/example/lib/page/developing/develop_prepare_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 |
4 | class ForPreparePage extends StatefulWidget {
5 | @override
6 | _ForPreparePageState createState() => _ForPreparePageState();
7 | }
8 |
9 | class _ForPreparePageState extends State {
10 | IjkMediaController controller = IjkMediaController();
11 |
12 | @override
13 | void initState() {
14 | super.initState();
15 | initPlayer();
16 | }
17 |
18 | @override
19 | void dispose() {
20 | controller.dispose();
21 | super.dispose();
22 | }
23 |
24 | @override
25 | Widget build(BuildContext context) {
26 | return Scaffold(
27 | appBar: AppBar(
28 | title: Text("prepare属性"),
29 | ),
30 | body: Column(
31 | children: [
32 | Container(
33 | child: IjkPlayer(mediaController: controller),
34 | height: 300,
35 | ),
36 | ],
37 | ),
38 | );
39 | }
40 |
41 | Future initPlayer() async {
42 | await controller.setDataSource(
43 | DataSource.asset("assets/sample1.mp4"),
44 | autoPlay: true,
45 | );
46 | controller.pause();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/example/lib/page/developing/live_interruption_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 | import 'package:ijkplayer_example/i18n/i18n.dart';
4 |
5 | /// 直播异常中断
6 | class LiveInterruptionPage extends StatefulWidget {
7 | @override
8 | _LiveInterruptionPageState createState() => _LiveInterruptionPageState();
9 | }
10 |
11 | class _LiveInterruptionPageState extends State {
12 | TextEditingController editingController = TextEditingController();
13 | IjkMediaController mediaController = IjkMediaController();
14 |
15 | @override
16 | void initState() {
17 | super.initState();
18 |
19 | editingController.text =
20 | "http://js.flv.huya.com/huyalive/94525224-2460685313-10568562945082523648-2789274524-10057-A-0-1.flv?wsSecret=9b67d35535b6956aec37815c21e43cc8&wsTime=5cbbea84&ratio=2000";
21 | }
22 |
23 | @override
24 | void dispose() {
25 | editingController.dispose();
26 | mediaController.dispose();
27 | super.dispose();
28 | }
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 | return Scaffold(
33 | appBar: AppBar(
34 | title: Text(currentI18n.networkButton),
35 | ),
36 | body: ListView(
37 | children: [
38 | Row(
39 | children: [
40 | Expanded(
41 | child: TextField(
42 | controller: editingController,
43 | ),
44 | ),
45 | FlatButton(
46 | child: Text(currentI18n.play),
47 | onPressed: _playInput,
48 | ),
49 | ],
50 | ),
51 | Container(
52 | height: 400,
53 | child: IjkPlayer(
54 | mediaController: mediaController,
55 | ),
56 | ),
57 | ],
58 | ),
59 | );
60 | }
61 |
62 | void _playInput() async {
63 | var text = editingController.text;
64 | await mediaController.setNetworkDataSource(text, autoPlay: true);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/example/lib/page/developing/new_full_screen_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 | import 'package:ijkplayer_example/const/video_datasource.dart';
4 |
5 | class NewFullScreenPage extends StatefulWidget {
6 | @override
7 | _NewFullScreenPageState createState() => _NewFullScreenPageState();
8 | }
9 |
10 | class _NewFullScreenPageState extends State {
11 | IjkMediaController controller;
12 |
13 | @override
14 | void initState() {
15 | super.initState();
16 | controller = IjkMediaController();
17 | controller.setDataSource(VideoDataSource.springBootMenuM3u8);
18 | }
19 |
20 | @override
21 | void dispose() {
22 | controller?.dispose();
23 | super.dispose();
24 | }
25 |
26 | @override
27 | Widget build(BuildContext context) {
28 | return Scaffold(
29 | appBar: AppBar(
30 | title: Text("New full screen"),
31 | ),
32 | body: Column(
33 | children: [
34 | AspectRatio(
35 | aspectRatio: 1920 / 1080,
36 | child: IjkPlayer(
37 | mediaController: controller,
38 | ),
39 | ),
40 | ],
41 | ),
42 | );
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/example/lib/page/developing/src_error_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 |
4 | class VideoWidget extends StatefulWidget {
5 | final String url;
6 | VideoWidget(this.url);
7 | @override
8 | _VideoWidgetState createState() => _VideoWidgetState();
9 | }
10 |
11 | class _VideoWidgetState extends State with WidgetsBindingObserver {
12 | IjkMediaController controller;
13 | @override
14 | void initState() {
15 | super.initState();
16 | controller = IjkMediaController();
17 | controller.setNetworkDataSource(widget.url, autoPlay: true);
18 | Stream ijkStatusStream = controller.ijkStatusStream;
19 | ijkStatusStream.listen((status) {
20 | if (status == IjkStatus.complete) {
21 | controller?.play();
22 | }
23 | });
24 | // SystemChannels.lifecycle.setMessageHandler((msg) {});
25 | }
26 |
27 | @override
28 | void didChangeAppLifecycleState(AppLifecycleState state) {
29 | if (state == AppLifecycleState.resumed) {
30 | controller?.play();
31 | } else if (state == AppLifecycleState.paused) {
32 | controller?.pause();
33 | }
34 | }
35 |
36 | @override
37 | void deactivate() {
38 | super.deactivate();
39 | controller?.pause();
40 | }
41 |
42 | @override
43 | void reassemble() {
44 | super.reassemble();
45 | controller?.play();
46 | }
47 |
48 | @override
49 | void dispose() {
50 | super.dispose();
51 | controller?.dispose();
52 | }
53 |
54 | @override
55 | Widget build(BuildContext context) {
56 | return IjkPlayer(
57 | mediaController: controller,
58 | controllerWidgetBuilder: (mController) => new Container(),
59 | );
60 | }
61 | }
62 |
63 | class SreErrorPage extends StatefulWidget {
64 | @override
65 | _SreErrorPageState createState() => _SreErrorPageState();
66 | }
67 |
68 | class _SreErrorPageState extends State {
69 | @override
70 | Widget build(BuildContext context) {
71 | return Scaffold(
72 | appBar: AppBar(),
73 | body: Container(
74 | child: PageView.builder(
75 | itemBuilder: (BuildContext context, int index) {
76 | // return VideoWidget("http://114.55.36.48/1204/27/index$index.m3u8");
77 | return VideoWidget(
78 | "http://itv.100.ahct.lv1.vcache.cn/100/ott_baseline_kalaok/hd/151/CP0541903573/playlist.m3u8");
79 | },
80 | ),
81 | ),
82 | );
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/example/lib/page/developing/test_hide_system_bar.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 |
4 | class TestHideSystemBar extends StatefulWidget {
5 | @override
6 | _TestHideSystemBarState createState() => _TestHideSystemBarState();
7 | }
8 |
9 | class _TestHideSystemBarState extends State {
10 | @override
11 | Widget build(BuildContext context) {
12 | return Scaffold(
13 | appBar: AppBar(
14 | title: Text("Test system bar"),
15 | ),
16 | body: Column(
17 | children: [
18 | FlatButton(
19 | child: Text("show"),
20 | onPressed: () => show(true),
21 | ),
22 | FlatButton(
23 | child: Text("hide"),
24 | onPressed: () => show(false),
25 | ),
26 | ],
27 | ),
28 | );
29 | }
30 |
31 | show(bool show) {
32 | IjkManager.showStatusBar(show);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/example/lib/page/dialog_video_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 | import 'package:ijkplayer_example/i18n/i18n.dart';
4 | import 'package:ijkplayer_example/utils/options_utils.dart';
5 |
6 | class DialogVideoPage extends StatefulWidget {
7 | @override
8 | _DialogVideoPageState createState() => _DialogVideoPageState();
9 | }
10 |
11 | class _DialogVideoPageState extends State {
12 | IjkMediaController controller = IjkMediaController();
13 |
14 | @override
15 | void initState() {
16 | super.initState();
17 | OptionUtils.addDefaultOptions(controller);
18 | }
19 |
20 | @override
21 | void dispose() {
22 | controller?.dispose();
23 | super.dispose();
24 | }
25 |
26 | @override
27 | Widget build(BuildContext context) {
28 | return Scaffold(
29 | appBar: AppBar(
30 | title: Text(currentI18n.withDialogButton),
31 | ),
32 | body: Center(
33 | child: Column(
34 | children: [
35 | FlatButton(
36 | child: Text(currentI18n.showDialog),
37 | onPressed: showIJKDialog,
38 | ),
39 | ],
40 | ),
41 | ),
42 | );
43 | }
44 |
45 | void showIJKDialog() async {
46 | await controller.setDataSource(
47 | DataSource.network(
48 | "http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4"),
49 | );
50 | await controller.play();
51 |
52 | await showDialog(
53 | context: context,
54 | builder: (_) => _buildIJKPlayer(),
55 | );
56 |
57 | controller.pause();
58 | }
59 |
60 | _buildIJKPlayer() {
61 | return IjkPlayer(
62 | mediaController: controller,
63 | );
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/example/lib/page/error_url.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 | import 'package:ijkplayer_example/const/video_datasource.dart';
4 | import 'package:ijkplayer_example/i18n/i18n.dart';
5 | import 'package:ijkplayer_example/utils/options_utils.dart';
6 |
7 | class ErrorUrlPage extends StatefulWidget {
8 | @override
9 | _ErrorUrlPageState createState() => _ErrorUrlPageState();
10 | }
11 |
12 | class _ErrorUrlPageState extends State {
13 | TextEditingController editingController = TextEditingController();
14 | IjkMediaController mediaController = IjkMediaController();
15 |
16 | // StreamSubscription statusSub;
17 | // StreamSubscription ijkErrorSub;
18 | @override
19 | void initState() {
20 | super.initState();
21 |
22 | // editingController.text =
23 | // "https://js.wshls.acgvideo.com/live-js/922199/live_8747041_1741679.m3u8?wsSecret=1337e20698b1673ac73ea8f35e2d60e8&wsTime=1556966389&trid=5afe0383d7d149dabe0c0327c2e53a75&order=1&sig=no";
24 |
25 | // statusSub = mediaController.ijkStatusStream.listen((status) {
26 | // print("status = $status");
27 | // });
28 |
29 | // ijkErrorSub = mediaController.ijkErrorStream.listen((error) {
30 | // print("error = $error");
31 | // });
32 | OptionUtils.addDefaultOptions(mediaController);
33 | mediaController.setDataSource(
34 | VideoDataSource.reportErrorM3u8FromAliyun,
35 | autoPlay: true,
36 | );
37 | }
38 |
39 | @override
40 | void dispose() {
41 | // statusSub?.cancel();
42 | // ijkErrorSub?.cancel();
43 | editingController.dispose();
44 | mediaController.dispose();
45 | super.dispose();
46 | }
47 |
48 | @override
49 | Widget build(BuildContext context) {
50 | return Scaffold(
51 | appBar: AppBar(
52 | title: Text(currentI18n.networkButton),
53 | ),
54 | body: ListView(
55 | children: [
56 | Row(
57 | children: [
58 | Expanded(
59 | child: TextField(
60 | controller: editingController,
61 | ),
62 | ),
63 | FlatButton(
64 | child: Text(currentI18n.play),
65 | onPressed: _playInput,
66 | ),
67 | ],
68 | ),
69 | Container(
70 | height: 400,
71 | child: IjkPlayer(
72 | mediaController: mediaController,
73 | ),
74 | ),
75 | ],
76 | ),
77 | );
78 | }
79 |
80 | void _playInput() async {
81 | var text = editingController.text;
82 | await mediaController.setNetworkDataSource(text, autoPlay: true);
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/example/lib/page/gallery_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 | import 'package:ijkplayer_example/i18n/i18n.dart';
4 | import 'package:photo/photo.dart';
5 | import 'package:photo_manager/photo_manager.dart';
6 |
7 | class PlayGalleryPage extends StatefulWidget {
8 | @override
9 | _PlayGalleryPageState createState() => _PlayGalleryPageState();
10 | }
11 |
12 | class _PlayGalleryPageState extends State {
13 | IjkMediaController mediaController = IjkMediaController();
14 |
15 | String mediaUrl;
16 |
17 | @override
18 | void initState() {
19 | super.initState();
20 | mediaController.addIjkPlayerOptions([
21 | TargetPlatform.iOS,
22 | TargetPlatform.android,
23 | ], [
24 | IjkOption(IjkOptionCategory.player, 'mediacodec', 1),
25 | IjkOption(IjkOptionCategory.player, 'mediacodec-hevc', 1),
26 | IjkOption(IjkOptionCategory.player, 'videotoolbox', 1),
27 | IjkOption(IjkOptionCategory.player, 'video-max-frame-width-default', 1),
28 | IjkOption(IjkOptionCategory.player, 'videotoolbox-max-frame-width', 1920),
29 | // IjkOption(IjkOptionCategory.player, 'videotoolbox-max-frame-width', 960),
30 | ]);
31 | }
32 |
33 | @override
34 | void dispose() {
35 | mediaController.dispose();
36 | super.dispose();
37 | }
38 |
39 | @override
40 | Widget build(BuildContext context) {
41 | return Scaffold(
42 | appBar: AppBar(
43 | title: Text(currentI18n.photoButton),
44 | ),
45 | body: ListView(
46 | children: [
47 | FlatButton(
48 | child: Text("Pick"),
49 | onPressed: _pickVideo,
50 | ),
51 | ListTile(
52 | title: Text("mediaUrl = $mediaUrl"),
53 | ),
54 | Container(
55 | height: 400,
56 | child: IjkPlayer(
57 | mediaController: mediaController,
58 | ),
59 | ),
60 | ],
61 | ),
62 | );
63 | }
64 |
65 | void _pickVideo() async {
66 | var assetList = await PhotoPicker.pickAsset(
67 | context: context,
68 | pickType: PickType.onlyVideo,
69 | maxSelected: 1,
70 | );
71 | if (assetList?.isNotEmpty == true) {
72 | var asset = assetList[0];
73 | _playVideo(asset);
74 | }
75 | }
76 |
77 | void _playVideo(AssetEntity asset) async {
78 | mediaUrl = await asset.getMediaUrl();
79 | setState(() {});
80 | final file = await asset.file;
81 | if (file != null && file.existsSync()) {
82 | await mediaController.setFileDataSource(file);
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/example/lib/page/ijk_status_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 | import 'package:ijkplayer_example/i18n/i18n.dart';
4 | import 'package:ijkplayer_example/utils/options_utils.dart';
5 |
6 | class IjkStatusPage extends StatefulWidget {
7 | @override
8 | _IjkStatusPageState createState() => _IjkStatusPageState();
9 | }
10 |
11 | class _IjkStatusPageState extends State {
12 | TextEditingController editingController = TextEditingController();
13 | IjkMediaController mediaController = IjkMediaController();
14 |
15 | @override
16 | void initState() {
17 | super.initState();
18 | editingController.text =
19 | "http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4";
20 | OptionUtils.addDefaultOptions(mediaController);
21 | }
22 |
23 | @override
24 | void dispose() {
25 | editingController.dispose();
26 | mediaController.dispose();
27 | super.dispose();
28 | }
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 | return Scaffold(
33 | appBar: AppBar(
34 | title: Text(currentI18n.ijkStatusTitle),
35 | ),
36 | body: ListView(
37 | children: [
38 | Row(
39 | children: [
40 | Expanded(
41 | child: TextField(
42 | controller: editingController,
43 | ),
44 | ),
45 | FlatButton(
46 | child: Text(currentI18n.play),
47 | onPressed: _playInput,
48 | ),
49 | ],
50 | ),
51 | AspectRatio(
52 | aspectRatio: 12 / 7,
53 | child: buildIjkPlayer(),
54 | ),
55 | ],
56 | ),
57 | );
58 | }
59 |
60 | void _playInput() async {
61 | var text = editingController.text;
62 | await mediaController.setNetworkDataSource(text, autoPlay: true);
63 | }
64 |
65 | Widget buildIjkPlayer() {
66 | return IjkPlayer(
67 | mediaController: mediaController,
68 | statusWidgetBuilder: _buildStatusWidget,
69 | );
70 | }
71 |
72 | Widget _buildStatusWidget(
73 | BuildContext context,
74 | IjkMediaController controller,
75 | IjkStatus status,
76 | ) {
77 | if (status == IjkStatus.noDatasource) {
78 | return Center(
79 | child: Text(
80 | "no data",
81 | style: TextStyle(color: Colors.white),
82 | ),
83 | );
84 | }
85 |
86 | // you can custom your self status widget
87 | return IjkStatusWidget.buildStatusWidget(context, controller, status);
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/example/lib/page/index.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 | import 'package:ijkplayer_example/page/paging_page.dart';
4 | import 'package:ijkplayer_example/page/screen_shot_page.dart';
5 | import 'package:ijkplayer_example/page/video_list.dart';
6 |
7 | import '../i18n/i18n.dart';
8 | import 'asset_page.dart';
9 | import 'auto_full_screen.dart';
10 | import 'controller_stream_use.dart';
11 | import 'custom_ijk_opt_page.dart';
12 | import 'developing/develop_index.dart';
13 | import 'dialog_video_page.dart';
14 | import 'error_url.dart';
15 | import 'full_screen.dart';
16 | import 'gallery_page.dart';
17 | import 'ijk_status_page.dart';
18 | import 'in_overlay_page.dart';
19 | import 'network.dart';
20 | import 'speed_page.dart';
21 |
22 | class IndexPage extends StatefulWidget {
23 | @override
24 | _IndexPageState createState() => _IndexPageState();
25 | }
26 |
27 | class _IndexPageState extends State {
28 | @override
29 | Widget build(BuildContext context) {
30 | return Scaffold(
31 | appBar: AppBar(
32 | title: Text(currentI18n.indexTitle),
33 | ),
34 | body: ListView(
35 | children: [
36 | buildButton("For developer, user don't use.", DevelopingIndexPage()),
37 | buildButton(currentI18n.networkButton, NetworkPage()),
38 | buildButton(currentI18n.photoButton, PlayGalleryPage()),
39 | buildButton(currentI18n.assetButton, AssetPage()),
40 | buildButton(currentI18n.listViewButton, VideoList()),
41 | buildButton(currentI18n.fullScreenAutoButton, FullScreen()),
42 | buildButton(currentI18n.fullScreenManualButton, FullScreen2()),
43 | buildButton(currentI18n.autoFullScreenOnPlay, AutoFullScreenPage()),
44 | buildButton(currentI18n.withDialogButton, DialogVideoPage()),
45 | buildButton(currentI18n.pageViewButton, PagingPickPage()),
46 | buildButton(currentI18n.useStreamUsage, ControllerStreamUsagePage()),
47 | buildButton(currentI18n.screenshotTitle, ScreenShotPage()),
48 | buildButton(currentI18n.overlayPageTitle, InOverlayPage()),
49 | buildButton(currentI18n.ijkStatusTitle, IjkStatusPage()),
50 | buildButton(currentI18n.customOption, CustomIjkOptionPage()),
51 | buildButton(currentI18n.errorUrl, ErrorUrlPage()),
52 | buildButton(currentI18n.setSpeed, SpeedPage()),
53 | buildButton(
54 | currentI18n.customFullScreenWidget, CustomFullControllerPage()),
55 | FlatButton(
56 | onPressed: () {
57 | IjkManager.initIJKPlayer();
58 | },
59 | child: Text("release all ijkplayer resource"),
60 | ),
61 | ],
62 | ),
63 | );
64 | }
65 |
66 | Widget buildButton(String text, Widget targetPage) {
67 | return FlatButton(
68 | onPressed: () {
69 | Navigator.push(context, MaterialPageRoute(builder: (_) => targetPage));
70 | },
71 | child: Text(text),
72 | );
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/example/lib/page/network.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 | import 'package:ijkplayer_example/i18n/i18n.dart';
4 | import 'package:ijkplayer_example/utils/options_utils.dart';
5 |
6 | class NetworkPage extends StatefulWidget {
7 | @override
8 | _NetworkPageState createState() => _NetworkPageState();
9 | }
10 |
11 | class _NetworkPageState extends State {
12 | TextEditingController editingController = TextEditingController();
13 | IjkMediaController mediaController = IjkMediaController();
14 |
15 | @override
16 | void initState() {
17 | super.initState();
18 |
19 | editingController.text =
20 | "https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_30mb.mp4";
21 |
22 | editingController.text =
23 | "http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4";
24 |
25 | // editingController.text =
26 | // "https://media001.geekbang.org/f433fd1ce5e84d27b1101f0dad72a126/de563bb4aba94b5f95f448b33be4dd9f-9aede6861be944d696fe365f3a33b7b4-sd.m3u8";
27 |
28 | // editingController.text =
29 | // "https://cctvalih5ca.v.myalicdn.com/live/cctv1_2/index.m3u8";
30 |
31 | // editingController.text = "http://222.207.48.30/hls/startv.m3u8";
32 |
33 | // editingController.text = "rtmp://172.16.100.245:1935/live1";
34 |
35 | // editingController.text = "http://172.16.100.245:5000/meng.mp4";
36 | // editingController.text = "http://172.16.100.245:5000/sample1.mp4";
37 | // editingController.text =
38 | // "http://172.16.100.245:5000/05-2%20ffmpeg%E5%BC%80%E5%8F%91%E5%85%A5%E9%97%A8Log%E7%B3%BB%E7%BB%9F.mp4";
39 | // editingController.text =
40 | // "http://172.16.100.245:5000/09-01%20%E7%AC%AC%E4%B8%80%E4%B8%AAJNI%E7%A8%8B%E5%BA%8F.mp4";
41 | // editingController.text = "http://172.16.100.245:5000/trailer.mp4";
42 |
43 | OptionUtils.addDefaultOptions(mediaController);
44 | }
45 |
46 | @override
47 | void dispose() {
48 | editingController.dispose();
49 | mediaController.dispose();
50 | super.dispose();
51 | }
52 |
53 | @override
54 | Widget build(BuildContext context) {
55 | return Scaffold(
56 | appBar: AppBar(
57 | title: Text(currentI18n.networkButton),
58 | ),
59 | body: ListView(
60 | children: [
61 | Row(
62 | children: [
63 | Expanded(
64 | child: TextField(
65 | controller: editingController,
66 | ),
67 | ),
68 | FlatButton(
69 | child: Text(currentI18n.play),
70 | onPressed: _playInput,
71 | ),
72 | ],
73 | ),
74 | Container(
75 | height: 400,
76 | child: IjkPlayer(
77 | mediaController: mediaController,
78 | ),
79 | ),
80 | ],
81 | ),
82 | );
83 | }
84 |
85 | void _playInput() async {
86 | var text = editingController.text;
87 | await mediaController.setNetworkDataSource(
88 | text,
89 | autoPlay: true,
90 | headers: {},
91 | );
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/example/lib/page/screen_shot_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:typed_data';
2 | import 'dart:async';
3 | import 'package:flutter/material.dart';
4 |
5 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
6 | import 'package:ijkplayer_example/i18n/i18n.dart';
7 | import 'dart:ui' as ui;
8 |
9 | import 'package:ijkplayer_example/utils/options_utils.dart';
10 |
11 | class ScreenShotPage extends StatefulWidget {
12 | @override
13 | _ScreenShotPageState createState() => _ScreenShotPageState();
14 | }
15 |
16 | class _ScreenShotPageState extends State {
17 | IjkMediaController mediaController = IjkMediaController();
18 |
19 | ImageProvider provider;
20 |
21 | @override
22 | void initState() {
23 | super.initState();
24 | OptionUtils.addDefaultOptions(mediaController);
25 | mediaController.setDataSource(
26 | DataSource.network(
27 | "http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4"),
28 | // "rtmp://58.200.131.2:1935/livetv/hunantv"),
29 | autoPlay: true);
30 | }
31 |
32 | @override
33 | void dispose() {
34 | mediaController.dispose();
35 | super.dispose();
36 | }
37 |
38 | @override
39 | Widget build(BuildContext context) {
40 | return Scaffold(
41 | appBar: AppBar(
42 | title: Text(currentI18n.screenshotTitle),
43 | ),
44 | body: ListView(
45 | children: [
46 | AspectRatio(
47 | aspectRatio: 1280 / 720,
48 | child: IjkPlayer(
49 | mediaController: mediaController,
50 | ),
51 | ),
52 | FlatButton(
53 | child: Text(currentI18n.screenshotTitle),
54 | onPressed: () async {
55 | var uint8List = await mediaController.screenShot();
56 | if (uint8List == null) {
57 | return;
58 | }
59 | provider = MemoryImage(uint8List);
60 | setState(() {});
61 | },
62 | ),
63 | provider == null
64 | ? Container()
65 | : Image(
66 | image: provider,
67 | ),
68 | ],
69 | ),
70 | );
71 | }
72 | }
73 |
74 | Future getImageForUint8List(Uint8List imageSrc) {
75 | Completer completer = Completer();
76 | ui.decodeImageFromList(imageSrc, (img) {
77 | completer.complete(Size(img.width.toDouble(), img.height.toDouble()));
78 | img.dispose();
79 | });
80 | return completer.future;
81 | }
82 |
--------------------------------------------------------------------------------
/example/lib/page/speed_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 | import 'package:ijkplayer_example/i18n/i18n.dart';
4 | import 'package:ijkplayer_example/utils/options_utils.dart';
5 |
6 | class SpeedPage extends StatefulWidget {
7 | @override
8 | _SpeedPageState createState() => _SpeedPageState();
9 | }
10 |
11 | class _SpeedPageState extends State {
12 | IjkMediaController controller = IjkMediaController();
13 |
14 | double speed = 1;
15 |
16 | @override
17 | void initState() {
18 | super.initState();
19 | var url = "http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4";
20 | var dataSource = DataSource.network(url);
21 |
22 | OptionUtils.addDefaultOptions(controller);
23 | controller?.setDataSource(dataSource, autoPlay: true);
24 | }
25 |
26 | @override
27 | void dispose() {
28 | controller.dispose();
29 | controller = null;
30 | super.dispose();
31 | }
32 |
33 | @override
34 | Widget build(BuildContext context) {
35 | return Scaffold(
36 | appBar: AppBar(
37 | title: Text(currentI18n.setSpeed),
38 | ),
39 | body: Container(
40 | child: ListView(
41 | children: [
42 | Container(
43 | height: 280,
44 | child: IjkPlayer(
45 | mediaController: controller,
46 | ),
47 | ),
48 | Slider(
49 | value: speed,
50 | max: 2,
51 | min: 0.5,
52 | divisions: 6,
53 | onChanged: _onChangeSpeed,
54 | ),
55 | Center(child: Text("speed is $speed")),
56 | ],
57 | ),
58 | ),
59 | );
60 | }
61 |
62 | void _onChangeSpeed(double value) {
63 | this.speed = value;
64 | setState(() {});
65 | controller?.setSpeed(speed);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/example/lib/page/video_list.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 | import 'package:ijkplayer_example/i18n/i18n.dart';
4 | import 'package:ijkplayer_example/utils/options_utils.dart';
5 |
6 | class VideoList extends StatefulWidget {
7 | @override
8 | _VideoListState createState() => _VideoListState();
9 | }
10 |
11 | class _VideoListState extends State {
12 | var list = [
13 | DataSource.network(
14 | "https://www.sample-videos.com/video123/mp4/360/big_buck_bunny_360p_30mb.mp4"),
15 | DataSource.network(
16 | "https://www.sample-videos.com/video123/mp4/360/big_buck_bunny_360p_30mb.mp4"),
17 | DataSource.asset("assets/sample1.mp4")
18 | ];
19 |
20 | var map = {};
21 |
22 | @override
23 | void initState() {
24 | super.initState();
25 | for (var data in list) {
26 | var controller = IjkMediaController();
27 | OptionUtils.addDefaultOptions(controller);
28 | map[data] = controller;
29 | // controller.setDataSource(data);
30 | }
31 | }
32 |
33 | @override
34 | void dispose() {
35 | map.values.forEach((c) {
36 | c.dispose();
37 | });
38 | super.dispose();
39 | }
40 |
41 | @override
42 | Widget build(BuildContext context) {
43 | return Scaffold(
44 | appBar: AppBar(
45 | title: Text(currentI18n.listViewButton),
46 | ),
47 | body: ListView.separated(
48 | itemBuilder: _buildItem,
49 | separatorBuilder: (BuildContext context, int index) {
50 | return Container(
51 | height: 10.0,
52 | color: Colors.blue,
53 | );
54 | },
55 | itemCount: list.length,
56 | ),
57 | );
58 | }
59 |
60 | Widget _buildItem(BuildContext context, int index) {
61 | return AspectRatio(
62 | child: VideoItem(list[index]),
63 | aspectRatio: 1280 / 500,
64 | );
65 | }
66 | }
67 |
68 | class VideoItem extends StatefulWidget {
69 | final DataSource dataSource;
70 |
71 | VideoItem(this.dataSource);
72 |
73 | @override
74 | _VideoItemState createState() => _VideoItemState();
75 | }
76 |
77 | class _VideoItemState extends State {
78 | IjkMediaController controller;
79 |
80 | var isInit = false;
81 | var isLoading = false;
82 |
83 | @override
84 | void initState() {
85 | super.initState();
86 | controller = IjkMediaController();
87 | }
88 |
89 | @override
90 | void dispose() {
91 | controller?.dispose();
92 | super.dispose();
93 | }
94 |
95 | @override
96 | Widget build(BuildContext context) {
97 | if (!isInit) {
98 | Widget stateButton = IconButton(
99 | icon: Icon(Icons.play_arrow),
100 | onPressed: _play,
101 | color: Colors.white,
102 | );
103 |
104 | if (isLoading) {
105 | stateButton = CircularProgressIndicator();
106 | }
107 |
108 | var center = Center(
109 | child: Container(
110 | width: 60.0,
111 | height: 60.0,
112 | child: stateButton,
113 | ),
114 | );
115 |
116 | return Stack(
117 | children: [
118 | Container(
119 | color: Colors.black,
120 | ),
121 | center,
122 | ],
123 | );
124 | }
125 |
126 | var ijkPlayer = IjkPlayer(
127 | mediaController: controller,
128 | controllerWidgetBuilder: _buildControllerWidget,
129 | );
130 | return ijkPlayer;
131 | }
132 |
133 | void _play() async {
134 | setState(() {
135 | isLoading = true;
136 | });
137 | await controller.setDataSource(widget.dataSource, autoPlay: true);
138 | await controller.pauseOtherController();
139 | setState(() {
140 | isLoading = false;
141 | isInit = true;
142 | });
143 | }
144 |
145 | Widget _buildControllerWidget(IjkMediaController controller) {
146 | return DefaultIJKControllerWidget(
147 | controller: controller,
148 | verticalGesture: false,
149 | );
150 | }
151 | }
152 |
153 | class PauseOtherNotification extends Notification {}
154 |
--------------------------------------------------------------------------------
/example/lib/utils/options_utils.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
3 |
4 | class OptionUtils {
5 | static void addDefaultOptions(IjkMediaController controller) {
6 | controller.addIjkPlayerOptions(
7 | [TargetPlatform.iOS, TargetPlatform.android],
8 | createIJKOptions(),
9 | );
10 | }
11 |
12 | static Set createIJKOptions() {
13 | return [
14 | IjkOption(IjkOptionCategory.player, "mediacodec", 1),
15 | IjkOption(IjkOptionCategory.player, "mediacodec-hevc", 1),
16 | IjkOption(IjkOptionCategory.player, "videotoolbox", 1),
17 | IjkOption(IjkOptionCategory.player, "opensles", 0),
18 | IjkOption(IjkOptionCategory.player, "overlay-format", 0x32335652),
19 | IjkOption(IjkOptionCategory.player, "framedrop", 1),
20 | IjkOption(IjkOptionCategory.player, "start-on-prepared", 0),
21 | IjkOption(IjkOptionCategory.format, "http-detect-range-support", 0),
22 | IjkOption(IjkOptionCategory.codec, "skip_loop_filter", 48),
23 | ].toSet();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/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.1.0 <3.0.0"
7 |
8 | dependencies:
9 | flutter:
10 | sdk: flutter
11 | # The following adds the Cupertino Icons font to your application.
12 | # Use with the CupertinoIcons class for iOS style icons.
13 | cupertino_icons: ^0.1.2
14 | photo: ^0.4.8
15 |
16 | oktoast: ^2.1.7
17 |
18 | flutter_localizations:
19 | sdk: flutter
20 | intl: ">=0.15.8 <1.0.0"
21 |
22 | flutter_ijkplayer:
23 | path: ../
24 |
25 | dependency_overrides:
26 | photo_manager:
27 | git:
28 | url: https://github.com/caijinglong/flutter_photo_manager.git
29 | ref: master
30 |
31 | dev_dependencies:
32 | flutter_test:
33 | sdk: flutter
34 |
35 | intl_translation: ^0.17.3
36 |
37 | # For information on the generic Dart part of this file, see the
38 | # following page: https://www.dartlang.org/tools/pub/pubspec
39 |
40 | # The following section is specific to Flutter.
41 | flutter:
42 | # The following line ensures that the Material Icons font is
43 | # included with your application, so that you can use the icons in
44 | # the material Icons class.
45 | uses-material-design: true
46 | # To add assets to your application, add an assets section, like this:
47 | # assets:
48 | # - images/a_dot_burr.jpeg
49 | # - images/a_dot_ham.jpeg
50 | assets:
51 | - assets/
52 | # An image asset can refer to one or more resolution-specific "variants", see
53 | # https://flutter.io/assets-and-images/#resolution-aware.
54 | # For details regarding adding assets from package dependencies, see
55 | # https://flutter.io/assets-and-images/#from-packages
56 | # To add custom fonts to your application, add a fonts section here,
57 | # in this "flutter" section. Each entry in this list should have a
58 | # "family" key with the font family name, and a "fonts" key with a
59 | # list giving the asset and other descriptors for the font. For
60 | # example:
61 | # fonts:
62 | # - family: Schyler
63 | # fonts:
64 | # - asset: fonts/Schyler-Regular.ttf
65 | # - asset: fonts/Schyler-Italic.ttf
66 | # style: italic
67 | # - family: Trajan Pro
68 | # fonts:
69 | # - asset: fonts/TrajanPro.ttf
70 | # - asset: fonts/TrajanPro_Bold.ttf
71 | # weight: 700
72 | #
73 | # For details regarding fonts from package dependencies,
74 | # see https://flutter.io/custom-fonts/#from-packages
75 |
--------------------------------------------------------------------------------
/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) =>
22 | widget is Text && 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/CaiJingLong/flutter_ijkplayer/468040c4222c26f65eb63ab22676362f9d350b9b/ios/Assets/.gitkeep
--------------------------------------------------------------------------------
/ios/Classes/CoolFlutterIJK.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Caijinglong on 2019-03-08.
3 | //
4 |
5 | #import
6 | #import
7 | #import "CoolIjkNotifyChannel.h"
8 | #import "CoolIjkOption.h"
9 |
10 | @interface CoolFlutterIJK : NSObject
11 |
12 | @property(nonatomic, strong) NSObject *registrar;
13 |
14 | @property(nonatomic, strong) NSArray *options;
15 |
16 | @property(nonatomic, assign) BOOL isDisposed;
17 |
18 | - (instancetype)initWithRegistrar:(NSObject *)registrar;
19 |
20 | + (instancetype)ijkWithRegistrar:(NSObject *)registrar;
21 |
22 | - (int64_t)id;
23 |
24 | - (void)dispose;
25 |
26 | - (void)setDegree:(int)degree;
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/ios/Classes/CoolFlutterIjkManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Caijinglong on 2019-03-08.
3 | //
4 |
5 | #import
6 | #import
7 |
8 | @class CoolFlutterIJK;
9 |
10 | @interface CoolFlutterIjkManager : NSObject
11 |
12 | @property(nonatomic, strong) NSObject *registrar;
13 |
14 | - (instancetype)initWithRegistrar:(NSObject *)registrar;
15 |
16 | + (instancetype)managerWithRegistrar:(NSObject *)registrar;
17 |
18 | - (int64_t)createWithCall:(FlutterMethodCall*) call;
19 |
20 | - (CoolFlutterIJK *)findIJKWithId:(int64_t)id1;
21 |
22 | - (int) ijkCount;
23 |
24 | - (void)disposeWithId:(int64_t)id;
25 |
26 | - (void)disposeAll;
27 | @end
28 |
--------------------------------------------------------------------------------
/ios/Classes/CoolFlutterIjkManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Caijinglong on 2019-03-08.
3 | //
4 |
5 | #import "CoolFlutterIjkManager.h"
6 | #import "CoolFlutterIJK.h"
7 | #import
8 | #import "CoolIjkOption.h"
9 |
10 | @implementation CoolFlutterIjkManager {
11 | NSMutableDictionary *dict;
12 | }
13 |
14 |
15 | - (instancetype)initWithRegistrar:(NSObject *)registrar {
16 | self = [super init];
17 | if (self) {
18 | self.registrar = registrar;
19 | dict = [NSMutableDictionary new];
20 | }
21 |
22 | return self;
23 | }
24 |
25 | + (instancetype)managerWithRegistrar:(NSObject *)registrar {
26 | return [[self alloc] initWithRegistrar:registrar];
27 | }
28 |
29 | - (int64_t)createWithCall:(FlutterMethodCall*) call {
30 | NSArray* options = [self getOptionsFromCall:call];
31 | CoolFlutterIJK *ijk = [CoolFlutterIJK ijkWithRegistrar:self.registrar];
32 | ijk.options = options;
33 | NSNumber *number = @([ijk id]);
34 | dict[number] = ijk;
35 | return [ijk id];
36 | }
37 |
38 | -(NSArray*)getOptionsFromCall:(FlutterMethodCall *)call{
39 | NSMutableArray *array = [NSMutableArray new];
40 |
41 | NSDictionary *args = call.arguments;
42 | NSArray *dartOptions = args[@"options"];
43 |
44 | for (NSDictionary *dict in dartOptions){
45 | int type = [dict[@"category"] intValue];
46 | NSString *key = dict[@"key"];
47 | id value = dict[@"value"];
48 | CoolIjkOption *option = [CoolIjkOption new];
49 | option.key = key;
50 | option.value = value;
51 | option.type = type;
52 |
53 | [array addObject:option];
54 | }
55 |
56 | return array;
57 | }
58 |
59 | - (CoolFlutterIJK *)findIJKWithId:(int64_t)id {
60 | return dict[@(id)];
61 | }
62 |
63 | - (int)ijkCount{
64 | if(!dict){
65 | return 0;
66 | }
67 | return [dict count];
68 | }
69 |
70 | - (void)disposeWithId:(int64_t)id {
71 | CoolFlutterIJK *ijk = dict[@(id)];
72 | if (ijk) {
73 | [ijk dispose];
74 | [dict removeObjectForKey:@(id)];
75 | }
76 | }
77 |
78 | - (void)disposeAll {
79 | NSArray *keys = dict.allKeys;
80 | for (NSNumber *key in keys) {
81 | CoolFlutterIJK *ijk = dict[key];
82 | [dict removeObjectForKey:key];
83 | [ijk dispose];
84 | }
85 | }
86 | @end
87 |
--------------------------------------------------------------------------------
/ios/Classes/CoolFlutterResult.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Caijinglong on 2019-06-12.
3 | //
4 |
5 |
6 | #import
7 |
8 | @interface CoolFlutterResult : NSObject
9 |
10 | @property(nonatomic, strong) FlutterResult result;
11 |
12 | @property(nonatomic, assign) BOOL isReply;
13 |
14 | - (instancetype)initWithResult:(FlutterResult)result;
15 |
16 | + (instancetype)resultWithResult:(FlutterResult)result;
17 |
18 | - (void)replyResult:(id _Nullable)result;
19 |
20 | @end
--------------------------------------------------------------------------------
/ios/Classes/CoolFlutterResult.m:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Caijinglong on 2019-06-12.
3 | //
4 |
5 | #import "CoolFlutterResult.h"
6 |
7 | @implementation CoolFlutterResult {
8 |
9 | }
10 | - (instancetype)initWithResult:(FlutterResult)result {
11 | self = [super init];
12 | if (self) {
13 | self.result = result;
14 | self.isReply = NO;
15 | }
16 |
17 | return self;
18 | }
19 |
20 | + (instancetype)resultWithResult:(FlutterResult)result {
21 | return [[self alloc] initWithResult:result];
22 | }
23 |
24 | - (void)replyResult:(id _Nullable)result {
25 | if (self.isReply) {
26 | return;
27 | }
28 | self.isReply = YES;
29 | self.result(result);
30 | }
31 |
32 |
33 | @end
--------------------------------------------------------------------------------
/ios/Classes/CoolIjkNotifyChannel.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Caijinglong on 2019-03-15.
3 | //
4 |
5 | #import
6 | #import
7 | #import
8 |
9 | @class CoolVideoInfo;
10 |
11 | @protocol KKIjkNotifyDelegate
12 | - (CoolVideoInfo *)getInfo;
13 |
14 | - (void)setDegree:(int)newDegree;
15 |
16 | - (void)onLoadStateChange;
17 | @end
18 |
19 | @interface CoolIjkNotifyChannel : NSObject
20 |
21 | @property(nonatomic, strong) IJKFFMoviePlayerController *controller;
22 |
23 | @property(nonatomic, assign) int64_t textureId;
24 |
25 | @property(nonatomic, strong) NSObject *registrar;
26 |
27 | @property(nonatomic, weak) NSObject *infoDelegate;
28 |
29 | - (instancetype)initWithController:(IJKFFMoviePlayerController *)controller textureId:(int64_t)textureId
30 | registrar:(NSObject *)registrar;
31 |
32 | + (instancetype)channelWithController:(IJKFFMoviePlayerController *)controller textureId:(int64_t)textureId
33 | registrar:(NSObject *)registrar;
34 |
35 |
36 | - (void)dispose;
37 |
38 | @end
--------------------------------------------------------------------------------
/ios/Classes/CoolIjkOption.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoolIjkOption.h
3 | // flutter_ijkplayer
4 | //
5 | // Created by Caijinglong on 2019/4/12.
6 | //
7 |
8 | #import
9 |
10 | NS_ASSUME_NONNULL_BEGIN
11 |
12 | @interface CoolIjkOption : NSObject
13 |
14 | @property(nonatomic,assign) int type;
15 | @property(nonatomic,copy) NSString *key;
16 | @property(nonatomic,copy) id value;
17 |
18 | @end
19 |
20 | NS_ASSUME_NONNULL_END
21 |
--------------------------------------------------------------------------------
/ios/Classes/CoolIjkOption.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoolIjkOption.m
3 | // flutter_ijkplayer
4 | //
5 | // Created by Caijinglong on 2019/4/12.
6 | //
7 |
8 | #import "CoolIjkOption.h"
9 |
10 | @implementation CoolIjkOption
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/ios/Classes/CoolVideoInfo.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Caijinglong on 2019-03-15.
3 | //
4 |
5 | #import
6 |
7 |
8 | @interface CoolVideoInfo : NSObject
9 |
10 | @property(nonatomic, assign) NSTimeInterval duration;
11 |
12 | @property(nonatomic, assign) NSTimeInterval currentPosition;
13 |
14 | @property(nonatomic, assign) CGSize size;
15 |
16 | @property(nonatomic, assign) BOOL isPlaying;
17 |
18 | @property(nonatomic, assign) int degree;
19 |
20 | /**
21 | * Unit is Byte.
22 | */
23 | @property(nonatomic, assign) int64_t tcpSpeed;
24 |
25 | @property(nonatomic, assign) CGFloat outputFps;
26 |
27 | - (NSDictionary *)toMap;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/ios/Classes/CoolVideoInfo.m:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Caijinglong on 2019-03-15.
3 | //
4 |
5 | #import "CoolVideoInfo.h"
6 |
7 |
8 | @implementation CoolVideoInfo {
9 |
10 | }
11 |
12 | - (instancetype)init {
13 | self = [super init];
14 | if (self) {
15 | self.degree = 0;
16 | }
17 |
18 | return self;
19 | }
20 |
21 |
22 | - (NSDictionary *)toMap {
23 | NSMutableDictionary *dict = [NSMutableDictionary new];
24 | dict[@"width"] = @((int) self.size.width);
25 | dict[@"height"] = @((int) self.size.height);
26 | dict[@"duration"] = @(self.duration);
27 | dict[@"currentPosition"] = @(self.currentPosition);
28 | dict[@"isPlaying"] = @(self.isPlaying);
29 | dict[@"degree"] = @(self.degree);
30 | dict[@"tcpSpeed"] = @(self.tcpSpeed);
31 | dict[@"outputFps"] = @(self.outputFps);
32 | return dict;
33 | }
34 |
35 | @end
--------------------------------------------------------------------------------
/ios/Classes/FlutterViewController+CoolStatusBarHidden.h:
--------------------------------------------------------------------------------
1 | //
2 | // FlutterViewController+CoolViewController.h
3 | // flutter_ijkplayer
4 | //
5 | // Created by Caijinglong on 2019/11/8.
6 | //
7 | #import
8 |
9 | NS_ASSUME_NONNULL_BEGIN
10 |
11 | @interface FlutterViewController (CoolViewController)
12 |
13 | -(void)showStatusBar;
14 |
15 | -(void)hideStatusBar;
16 |
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/ios/Classes/FlutterViewController+CoolStatusBarHidden.m:
--------------------------------------------------------------------------------
1 | //
2 | // FlutterViewController+CoolViewController.m
3 | // flutter_ijkplayer
4 | //
5 | // Created by Caijinglong on 2019/11/8.
6 | //
7 |
8 | #import "FlutterViewController+CoolStatusBarHidden.h"
9 | #import
10 |
11 | @implementation FlutterViewController (CoolViewController)
12 |
13 | -(void)showStatusBar{
14 | objc_setAssociatedObject(self, @selector(showStatusBar), @"show", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
15 | [UIView animateWithDuration:1 animations:^{
16 | [self setNeedsStatusBarAppearanceUpdate];
17 | }];
18 | }
19 |
20 | -(void)hideStatusBar{
21 | objc_setAssociatedObject(self, @selector(showStatusBar), @"hide", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
22 | [UIView animateWithDuration:1 animations:^{
23 | [self setNeedsStatusBarAppearanceUpdate];
24 | }];
25 | }
26 |
27 | -(BOOL)isStatusBarShow{
28 | NSString *value = objc_getAssociatedObject(self, @selector(showStatusBar));
29 | return ![value isEqualToString:@"hide"];
30 | }
31 |
32 | - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation{
33 | return UIStatusBarAnimationFade;
34 | }
35 |
36 | -(BOOL)prefersStatusBarHidden{
37 | return ![self isStatusBarShow];
38 | }
39 |
40 | -(void)viewDidDisappear:(BOOL)animated{
41 | objc_removeAssociatedObjects(self);
42 | }
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/ios/Classes/IjkplayerPlugin.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface IjkplayerPlugin : NSObject
4 |
5 | @property(nonatomic, strong) NSObject *registrar;
6 |
7 | - (instancetype)initWithRegistrar:(NSObject *)registrar;
8 |
9 | + (instancetype)pluginWithRegistrar:(NSObject *)registrar;
10 |
11 | + (instancetype)sharedInstance;
12 |
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/ios/flutter_ijkplayer.dev.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 = 'flutter_ijkplayer'
6 | s.version = '0.0.1'
7 | s.summary = 'IjkPlayer plugin for flutter'
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 = { 'Caijinglong' => 'cjl_spy@163.com' }
14 | s.source = { :path => '.' }
15 | s.source_files = 'Classes/**/*' , 'IJKMediaFramework.framework'
16 | s.public_header_files = 'Classes/**/*.h'
17 | s.dependency 'Flutter'
18 | s.static_framework = true
19 | s.ios.deployment_target = '8.0'
20 |
21 | s.ios.vendored_frameworks = 'IJKMediaFramework.framework'
22 | s.frameworks = "AudioToolbox", "AVFoundation", "CoreGraphics", "CoreMedia", "CoreVideo", "MobileCoreServices", "OpenGLES", "QuartzCore", "VideoToolbox", "Foundation", "UIKit", "MediaPlayer"
23 | s.libraries = "bz2", "z", "stdc++"
24 | # s.dependency 'FlutterIJK', '~> 0.1.0'
25 |
26 | # s.script_phase = {:name => 'extract framework', :script=> 'echo "Hello World"; pwd' ,:execution_position => :before_compile}
27 |
28 | end
29 |
30 |
--------------------------------------------------------------------------------
/ios/flutter_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 = 'flutter_ijkplayer'
6 | s.version = '0.0.1'
7 | s.summary = 'IjkPlayer plugin for flutter'
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 = { 'Caijinglong' => 'cjl_spy@163.com' }
14 | s.source = { :path => '.' }
15 | s.source_files = 'Classes/**/*' , 'IJKMediaFramework.framework'
16 | s.public_header_files = 'Classes/**/*.h'
17 | s.dependency 'Flutter'
18 | s.static_framework = true
19 | s.ios.deployment_target = '8.0'
20 |
21 | # s.ios.vendored_frameworks = 'IJKMediaFramework.framework'
22 | # s.frameworks = "AudioToolbox", "AVFoundation", "CoreGraphics", "CoreMedia", "CoreVideo", "MobileCoreServices", "OpenGLES", "QuartzCore", "VideoToolbox", "Foundation", "UIKit", "MediaPlayer"
23 | # s.libraries = "bz2", "z", "stdc++"
24 | s.dependency 'FlutterIJK', '~> 0.2.3'
25 |
26 | # s.script_phase = {:name => 'extract framework', :script=> 'echo "Hello World"; pwd' ,:execution_position => :before_compile}
27 |
28 | end
29 |
30 |
--------------------------------------------------------------------------------
/ios/flutter_ijkplayer.prod.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 = 'flutter_ijkplayer'
6 | s.version = '0.0.1'
7 | s.summary = 'IjkPlayer plugin for flutter'
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 = { 'Caijinglong' => 'cjl_spy@163.com' }
14 | s.source = { :path => '.' }
15 | s.source_files = 'Classes/**/*' , 'IJKMediaFramework.framework'
16 | s.public_header_files = 'Classes/**/*.h'
17 | s.dependency 'Flutter'
18 | s.static_framework = true
19 | s.ios.deployment_target = '8.0'
20 |
21 | # s.ios.vendored_frameworks = 'IJKMediaFramework.framework'
22 | # s.frameworks = "AudioToolbox", "AVFoundation", "CoreGraphics", "CoreMedia", "CoreVideo", "MobileCoreServices", "OpenGLES", "QuartzCore", "VideoToolbox", "Foundation", "UIKit", "MediaPlayer"
23 | # s.libraries = "bz2", "z", "stdc++"
24 | s.dependency 'FlutterIJK', '~> 0.2.3'
25 |
26 | # s.script_phase = {:name => 'extract framework', :script=> 'echo "Hello World"; pwd' ,:execution_position => :before_compile}
27 |
28 | end
29 |
30 |
--------------------------------------------------------------------------------
/ios/switch_local.sh:
--------------------------------------------------------------------------------
1 | if [ "$1" == "dev" ]; then
2 | rm IJKMediaFramework.framework
3 | ln -s /Volumes/Samsung-T5/code/media_projects/ijkplayer/flutter_ijk/ios/output/IJKMediaFramework.framework IJKMediaFramework.framework
4 | rm flutter_ijkplayer.podspec
5 | ln flutter_ijkplayer.dev.podspec flutter_ijkplayer.podspec
6 | echo 'switch to local'
7 | elif [ "$1" == "prod" ]; then
8 | rm IJKMediaFramework.framework
9 | rm flutter_ijkplayer.podspec
10 | ln flutter_ijkplayer.prod.podspec flutter_ijkplayer.podspec
11 | echo 'switch to pod version'
12 | else
13 | echo "Switch dev or product"
14 | echo "Usage:"
15 | echo " $0 dev|prod"
16 | fi
17 |
--------------------------------------------------------------------------------
/lib/flutter_ijkplayer.dart:
--------------------------------------------------------------------------------
1 | export 'src/error.dart';
2 | export 'src/ijkplayer.dart';
3 | export 'src/entity/video_info.dart';
4 | export 'src/entity/options.dart';
5 | export 'src/widget/controller_widget_builder.dart'
6 | show DefaultIJKControllerWidget,DefaultIJKControllerWidgetState, VolumeType, FullScreenType;
7 | export 'src/helper/config.dart';
8 | export 'src/widget/ijk_status_widget.dart'
9 | show IjkStatusWidget, StatusWidgetBuilder;
10 |
--------------------------------------------------------------------------------
/lib/src/controller/datasoure.dart:
--------------------------------------------------------------------------------
1 | part of '../ijkplayer.dart';
2 |
3 | /// Entity classe for data sources.
4 | class DataSource {
5 | /// See [DataSourceType]
6 | DataSourceType _type;
7 |
8 | File _file;
9 |
10 | String _assetName;
11 |
12 | String _assetPackage;
13 |
14 | String _netWorkUrl;
15 |
16 | Map _headers;
17 |
18 | String _mediaUrl;
19 |
20 | DataSource._();
21 |
22 | /// Create file data source
23 | factory DataSource.file(File file) {
24 | final ds = DataSource._();
25 | ds._file = file;
26 | ds._type = DataSourceType.file;
27 | return ds;
28 | }
29 |
30 | /// Create network data source
31 | factory DataSource.network(String url,
32 | {Map headers = const {}}) {
33 | final ds = DataSource._();
34 | ds._netWorkUrl = url;
35 | ds._headers = headers;
36 | ds._type = DataSourceType.network;
37 | return ds;
38 | }
39 |
40 | /// Create asset data source
41 | factory DataSource.asset(String assetName, {String package}) {
42 | final ds = DataSource._();
43 | ds._assetName = assetName;
44 | ds._assetPackage = package;
45 | ds._type = DataSourceType.asset;
46 | return ds;
47 | }
48 |
49 | /// Create for [photo_manager](https://pub.dev/packages/photo_manager) library. [AssetEntity.mediaUrl]
50 | factory DataSource.photoManagerUrl(String mediaUrl) {
51 | final ds = DataSource._();
52 | ds._mediaUrl = mediaUrl;
53 | ds._type = DataSourceType.photoManager;
54 | return ds;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/lib/src/controller/enums.dart:
--------------------------------------------------------------------------------
1 | part of '../ijkplayer.dart';
2 |
3 | enum DataSourceType {
4 | network,
5 | file,
6 | asset,
7 | photoManager,
8 | }
9 |
10 | /// Current IjkMedia status
11 | enum IjkStatus {
12 | noDatasource,
13 | preparing,
14 | setDatasourceFail,
15 | prepared,
16 | pause,
17 | error,
18 | playing,
19 | complete,
20 | disposed,
21 | }
22 |
--------------------------------------------------------------------------------
/lib/src/controller/ijk_event_channel.dart:
--------------------------------------------------------------------------------
1 | part of '../ijkplayer.dart';
2 |
3 | class _IJKEventChannel {
4 | int get textureId => controller?.textureId;
5 |
6 | IjkMediaController controller;
7 |
8 | _IJKEventChannel(this.controller);
9 |
10 | MethodChannel channel;
11 |
12 | String get channelName => "top.kikt/ijkplayer/event/$textureId";
13 |
14 | Completer _prepareCompleter;
15 |
16 | bool _isDisposed = false;
17 |
18 | bool get isDisposed => _isDisposed;
19 |
20 | Future init() async {
21 | channel = MethodChannel(channelName);
22 | channel.setMethodCallHandler(handler);
23 | }
24 |
25 | void dispose() {
26 | _isDisposed = true;
27 | channel.setMethodCallHandler(null);
28 | controller = null;
29 | }
30 |
31 | Future handler(MethodCall call) async {
32 | switch (call.method) {
33 | case "finish": // 播放完毕
34 | // var index = call.arguments["type"];
35 | // var type = FinishType.values[index];
36 | _onPlayFinish(getInfo(call));
37 | break;
38 | case "playStateChange":
39 | onPlayStateChange(getInfo(call));
40 | break;
41 | case "prepare":
42 | onPrepare(getInfo(call));
43 | break;
44 | case "rotateChanged":
45 | onRotateChanged(call);
46 | break;
47 | case "error":
48 | var info = await controller.getVideoInfo();
49 | _onPlayFinish(info);
50 | int errorValue = call.arguments;
51 | _onPlayError(errorValue);
52 | break;
53 | default:
54 | return MissingPluginException(
55 | "$channelName ${call.method} not implement",
56 | );
57 | }
58 | return true;
59 | }
60 |
61 | VideoInfo getInfo(MethodCall call) {
62 | var map = call.arguments.cast();
63 | return VideoInfo.fromMap(map);
64 | }
65 |
66 | void _onPlayFinish(VideoInfo info) {
67 | controller?._onPlayFinish();
68 | }
69 |
70 | void onPlayStateChange(VideoInfo info) {
71 | controller.isPlaying = info.isPlaying;
72 | }
73 |
74 | void onPrepare(VideoInfo info) {
75 | controller.isPlaying = info.isPlaying;
76 | _prepareCompleter?.complete();
77 | _prepareCompleter = null;
78 | }
79 |
80 | Future waitPrepare() {
81 | _prepareCompleter = Completer();
82 | return _prepareCompleter.future;
83 | }
84 |
85 | Future autoPlay(IjkMediaController ijkMediaController) async {
86 | try {
87 | await waitPrepare();
88 | await ijkMediaController.play();
89 | } catch (e) {
90 | LogUtils.info(e);
91 | }
92 | }
93 |
94 | Future disableAutoPlay(IjkMediaController ijkMediaController) async {
95 | try {
96 | await waitPrepare();
97 | await ijkMediaController.pause();
98 | } catch (e) {
99 | LogUtils.info(e);
100 | }
101 | }
102 |
103 | void onRotateChanged(MethodCall call) {
104 | var info = getInfo(call);
105 | LogUtils.debug("onRotateChanged , info = $info");
106 | }
107 |
108 | void _onPlayError(int errorValue) {
109 | LogUtils.warning("play error , errorValue : $errorValue");
110 | controller._onError(errorValue);
111 | }
112 | }
113 |
114 | // enum FinishType {
115 | // playEnd,
116 | // userExit,
117 | // error,
118 | // }
119 |
--------------------------------------------------------------------------------
/lib/src/controller/plugin.dart:
--------------------------------------------------------------------------------
1 | part of '../ijkplayer.dart';
2 |
3 | /// about channel
4 | MethodChannel _globalChannel = MethodChannel("top.kikt/ijkplayer");
5 |
6 | Future _createIjk({
7 | List options,
8 | }) async {
9 | List