{"id":15475861,"url":"https://github.com/caijinglong/flutter_ijkplayer","last_synced_at":"2025-04-12T21:31:15.560Z","repository":{"id":40932312,"uuid":"174318970","full_name":"CaiJingLong/flutter_ijkplayer","owner":"CaiJingLong","description":"ijkplayer for flutter","archived":false,"fork":false,"pushed_at":"2022-12-10T09:27:05.000Z","size":29801,"stargazers_count":789,"open_issues_count":121,"forks_count":149,"subscribers_count":13,"default_branch":"master","last_synced_at":"2024-10-30T00:37:25.496Z","etag":null,"topics":["ffmpeg","flutter","ijkplayer","media","player","video"],"latest_commit_sha":null,"homepage":"","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CaiJingLong.png","metadata":{"files":{"readme":"README-EN.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-07T10:01:44.000Z","updated_at":"2024-10-16T14:41:26.000Z","dependencies_parsed_at":"2022-09-21T00:43:51.448Z","dependency_job_id":null,"html_url":"https://github.com/CaiJingLong/flutter_ijkplayer","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CaiJingLong%2Fflutter_ijkplayer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CaiJingLong%2Fflutter_ijkplayer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CaiJingLong%2Fflutter_ijkplayer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CaiJingLong%2Fflutter_ijkplayer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CaiJingLong","download_url":"https://codeload.github.com/CaiJingLong/flutter_ijkplayer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248635273,"owners_count":21137202,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ffmpeg","flutter","ijkplayer","media","player","video"],"created_at":"2024-10-02T03:20:51.698Z","updated_at":"2025-04-12T21:31:15.500Z","avatar_url":"https://github.com/CaiJingLong.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ijkplayer\n\n[![pub package](https://img.shields.io/pub/v/flutter_ijkplayer.svg)](https://pub.dartlang.org/packages/flutter_ijkplayer)\n\nijkplayer for [bilibili/ijkplayer](https://github.com/bilibili/ijkplayer), use flutter Texture widget.\nRead this README and refer to example/lib/main.dart before using it.\nThe question of Android might not be able to run will be explained in detail.\nThe simulator is out of use, so please use the real machine for debugging.\n\n- Android: I added the so Library of x86, but my voice decoding here is abnormal.\n- iOS: The simulator library is added, but it has sound and no video. It's normal in real device.\n\nBefore using library, you can star and download the code to try the example.\n\n- [ijkplayer](#ijkplayer)\n  - [Install](#install)\n  - [Build](#build)\n    - [Custom compile library](#custom-compile-library)\n    - [iOS](#ios)\n    - [Android](#android)\n  - [Simple Example](#simple-example)\n  - [Usage](#usage)\n    - [Usage of ijkplayer](#usage-of-ijkplayer)\n    - [about dispose](#about-dispose)\n    - [Usage of controller](#usage-of-controller)\n      - [DataSource](#datasource)\n      - [control your media](#control-your-media)\n      - [get media info](#get-media-info)\n      - [screen shot](#screen-shot)\n      - [Observer for resource](#observer-for-resource)\n      - [Media Speed](#media-speed)\n      - [IjkStatus](#ijkstatus)\n      - [Custom Options](#custom-options)\n        - [IjkOptionCategory](#ijkoptioncategory)\n      - [release resource](#release-resource)\n    - [Use self controller UI](#use-self-controller-ui)\n    - [Build widget from IjkStatus](#build-widget-from-ijkstatus)\n    - [Use Texture widget](#use-texture-widget)\n  - [LICENSE](#license)\n\n## Install\n\n[![pub package](https://img.shields.io/pub/v/flutter_ijkplayer.svg)](https://pub.dartlang.org/packages/flutter_ijkplayer)\n\npubspec.yaml\n\n```yaml\ndependencies:\n  flutter_ijkplayer: ${latest_version}\n```\n\n## Build\n\n### Custom compile library\n\nCurrent config file see [url](https://gitee.com/kikt/ijkplayer_thrid_party/blob/master/config/module.sh).\n\nFor custom configuration options, refer to the [bibibili/ijkplayer](https://github.com/bilibili/ijkplayer) or [ffmpeg](http://ffmpeg.org/).\n\nCustom compilation source document:\nhttps://github.com/CaiJingLong/flutter_ijkplayer/blob/master/compile.md\n\nBecause I edit some source, so you must see the compile.md to customize your library.\n\n### iOS\n\nBecause the libraries of some iOS codes are large, a pod-dependent ijkplayer library for hosting iOS is created.\nThe pod library is hosted in the GitHub repository at https://github.com/CaiJingLong/flutter_ijkplayer_pod\nInstead of tar.gz or zip, we use tar.xz to compress. This compression format has high compression rate, but slow compression and decompression speed. Considering the way of high compression rate, we should use high compression rate.\nIf a friend is willing to provide CDN acceleration, you can contact me\nThe ios part of the code is based on the https://github.com/jadennn/flutter_ijk.\nAdd some change rotation notification is added.\n\nNow, the code in the [repository](https://gitee.com/kikt/ijkplayer_thrid_party)\n\n### Android\n\nNow, use compilation options in [GSYVideoPlayer](https://github.com/CarGuo/GSYVideoPlayer).\n\n## Simple Example\n\n```dart\nimport 'package:flutter_ijkplayer/flutter_ijkplayer.dart';\n\n\nclass HomePageState extends State\u003cHomePage\u003e {\n  IjkMediaController controller = IjkMediaController();\n\n  @override\n  void initState() {\n    super.initState();\n  }\n\n  @override\n  void dispose() {\n    controller.dispose();\n    super.dispose();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: const Text('Plugin example app'),\n        actions: \u003cWidget\u003e[\n          IconButton(\n            icon: Icon(Icons.videocam),\n            onPressed: _pickVideo,\n          ),\n        ],\n      ),\n      body: Container(\n        // width: MediaQuery.of(context).size.width,\n        // height: 400,\n        child: ListView(\n          children: \u003cWidget\u003e[\n            buildIjkPlayer(),\n          ]\n        ),\n      ),\n      floatingActionButton: FloatingActionButton(\n        child: Icon(Icons.play_arrow),\n        onPressed: () async {\n          await controller.setNetworkDataSource(\n              'https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4',\n              // 'rtmp://172.16.100.245/live1',\n              // 'https://www.sample-videos.com/video123/flv/720/big_buck_bunny_720p_10mb.flv',\n//              \"https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4\",\n              // 'http://184.72.239.149/vod/smil:BigBuckBunny.smil/playlist.m3u8',\n              // \"file:///sdcard/Download/Sample1.mp4\",\n              autoPlay: true);\n          print(\"set data source success\");\n          // controller.playOrPause();\n        },\n      ),\n    );\n  }\n\n  Widget buildIjkPlayer() {\n    return Container(\n      // height: 400,\n      child: IjkPlayer(\n        mediaController: controller,\n      ),\n    );\n  }\n}\n```\n\n## Usage\n\n### Usage of ijkplayer\n\n```dart\nIjkMediaController controller = IjkMediaController();\n```\n\n```dart\n  var ijkplayer = IjkPlayer(\n    mediaController: controller,\n  );\n```\n\n### about dispose\n\nUsers need to call `dispose` method to release resources when they decide that they will no longer use controllers. If they do not call `dispose` method, the resources will not be released.\n\nSince a `controller` may be attached by multiple `IjkPlayers`, leading to a `controller` controlling multiple `IjkPlayers`, it is not in principle possible to agree with `dispose`of `IjkPlayer`, so the caller needs to dispose of itself here.\n\n```dart\ncontroller.dispose();\n```\n\n### Usage of controller\n\n#### DataSource\n\n```dart\n// network\nawait controller.setNetworkDataSource(\"https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4\");\n\n// Custom headers for network source\nawait controller.setNetworkDataSource(url, headers: \u003cString,String\u003e{});\n\n// asset\nawait controller.setAssetDataSource(\"assets/test.mp4\");\n\n// file\nawait controller.setFileDataSource(File(\"/sdcard/1.mp4\"));\n\n// For photo_manager mediaUrl, Hundreds of MB of album files do not need to be cached as files to use.\nawait controller.setPhotoManagerDataSource(await assetEntity.getMediaUrl());\n\n// dataSource\nvar dataSource = DataSource.file(File(\"/sdcard/1.mp4\"));\nvar dataSource = DataSource.network(\"https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4\", headers:\u003cString,String\u003e{});\nvar dataSource = DataSource.asset(\"assets/test.mp4\");\nvar dataSource = DataSource.photoManagerUrl(await assetEntity.getMediaUrl());\nawait controller.setDataSource(dataSource);\n\n\n// autoplay param\nawait controller.setNetworkDataSource(\"https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4\",autoPlay : true);\n\n// or use play()\nawait controller.setNetworkDataSource(\"https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4\");\nawait controller.play();\n```\n\n#### control your media\n\n```dart\n// play or pause your media\nawait controller.playOrPause();\n\n// play your media\nawait controller.play();\n\n// pause your media\nawait controller.pause();\n\n// stop\n// Here I want to explain that ijkplayer's stop releases resources, which makes play unusable and requires re-preparation of resources. So, in fact, this is to go back to the progress bar and pause.\nawait controller.stop();\n\n// seek progress to\nawait controller.seekTo(0); // double value , such as : 1.1 = 1s100ms, 60 = 1min\n```\n\n#### get media info\n\n```dart\n  // have some properties, width , height , duration\n  VideoInfo info = await controller.getVideoInfo();\n```\n\n#### screen shot\n\nIntercept the current video frame\nThis video frame comes from the video frame currently decoded by ffmpeg and does not contain the contents of the controller, etc.\nThe format in dart is Uint8List.\n\n```dart\nvar uint8List = await controller.screenShot();\nvar provider = MemoryImage(uint8List);\nWidget image = Image(image:provider);\n```\n\n**This is not always the same as the video on display. This is because it intercepts the decoded full video frame, which may be 1-2 frames faster than the current play.** If you can't accept it, please don't use this feature or submit a viable PR.\n\n#### Observer for resource\n\nBroadcasting changes in information outward in the form of streams, in principle the attributes ending with streams are monitorable.\n\n```dart\n// Callback when texture ID changes\nStream\u003cint\u003e textureIdStream = controller.textureIdStream;\n\n// Play status monitoring, true is playing, false is pausing\nStream\u003cbool\u003e playingStream = controller.playingStream;\n\n// When controller. refreshVideoInfo () is called, this method calls back, usually for the customization of the controller UI, so as to monitor the current information (playback progress, playback status, width, height, direction change, etc.).\nStream\u003cVideoInfo\u003e videoInfoStream = controller.videoInfoStream;\n\n// Volume change, which should be noted here, refers to the volume change of the current media, not the volume change of the system.\nStream\u003cbool\u003e volumeStream = controller.playingStream;\n\n// When the state changes, the stream is called.\n// Detailed descriptions of specific states can be seen in the table below.\nStream\u003cIjkStatus\u003e ijkStatusStream = controller.ijkStatusStream;\n\n```\n\n#### Media Speed\n\ncode:\n\n```dart\ncontroller.setSpeed(2.0);\n```\n\nDefault speed is 1.0, the min value need bigger than 0\n\nBecause of the speed change, the tone will change. So you need to use an option to keep the tone unchanged. The option **default value is open**, and if you want to close it, use the code:\n\n```dart\nIjkMediaController(needChangeSpeed: false); // set needChangeSpeed to false, the tone will change on speed change.\n```\n\n#### IjkStatus\n\n| name              | describe                                                       |\n| ----------------- | -------------------------------------------------------------- |\n| noDatasource      | The initial state, or the state after calling the reset method |\n| preparing         | After setting up src, get ready before src.                    |\n| setDatasourceFail | After setting datasource failed.                               |\n| prepared          | The datasource was prepared.                                   |\n| pause             | Media pause.                                                   |\n| error             | An error occurred in playback.                                 |\n| playing           | Media is playing.                                              |\n| complete          | Media is play complete.                                        |\n| disposed          | After Controller calls `dispose()`.                            |\n\n#### Custom Options\n\n**This function may cause problems, such as not playing, etc.** Stop using this feature if you find that you cannot use or have an exception after setting options.\n\nSupport custom IJKPlayer options, which are transmitted directly to Android/iOS native. For specific values and meanings, you need to see bilibili/ijkplayer](https://github.com/bilibili/ijkplayer).\n\nHowever, this option does not take effect immediately.\nIt will only take effect if you call `setDataSource` again.\n\nSetup method `setIjkPlayerOptions`\n\n```dart\nvoid initIjkController() async {\n  var option1 = IjkOption(IjkOptionCategory.format, \"fflags\", \"fastseek\");// category, key ,value\n\n  controller.setIjkPlayerOptions(\n    [TargetPlatform.iOS, TargetPlatform.android],\n    [option1].toSet(),\n  );\n\n  await controller.setDataSource(\n    DataSource.network(\n        \"http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4\"),\n    autoPlay: true,\n  );\n}\n```\n\nThe first parameter is an array that represents the type of device you choose to target (android/iOS).\n\nThe second parameter is a `Set\u003cIjkOption\u003e`, which represents the set of Option, because both categories and keys are covered, so set is used here.\n\n##### IjkOptionCategory\n\n| name   |\n| ------ |\n| format |\n| codec  |\n| sws    |\n| player |\n\n#### release resource\n\n```dart\nawait controller.reset(); // When this method is called, all native resources are released, but the dataSource is still available for resetting.\n\nawait controller.dispose(); // After this method call, the current controller is theoretically no longer available, resetting dataSource is invalid and may throw an exception.\n```\n\n### Use self controller UI\n\nUse `IJKPlayer`'s `controllerWidgetBuilder` params can customize UI, default use `defaultBuildIjkControllerWidget` method to get widget.\n\nThe type def sign: `typedef Widget IJKControllerWidgetBuilder(IjkMediaController controller);`\n\nThe returned widget will be overwritten on the `Texture`.\n\n```dart\nIJKPlayer(\n  mediaController: IjkMediaController(),\n  controllerWidgetBuilder: (mediaController){\n    return Container(); // your controller widget.\n  },\n);\n```\n\nThe library use `DefaultIJKControllerWidget` to build the widget.\n\nThis class provides some properties for customization. All properties except `controller` are optional:\n\n|               name                |            type            |         default          |                                          desc                                          |\n| :-------------------------------: | :------------------------: | :----------------------: | :------------------------------------------------------------------------------------: |\n|           doubleTapPlay           |            bool            |          false           |                                doubleTap gesture switch                                |\n|          verticalGesture          |            bool            |           true           |                                vertical gesture switch                                 |\n|         horizontalGesture         |            bool            |           true           |                               horizontal gesture switch                                |\n|            volumeType             |         VolumeType         |    VolumeType.system     |               vertical gesture changes the type of sound (system,media)                |\n|        playWillPauseOther         |            bool            |           true           |                         play the video will pause other medias                         |\n|      currentFullScreenState       |            bool            |          false           |     **If you are customizing the full screen interface, this must be set to true**     |\n|       showFullScreenButton        |            bool            |           true           |                       Whether to display the full screen button                        |\n| fullscreenControllerWidgetBuilder | IJKControllerWidgetBuilder |                          |                        Can customize the full screen interface                         |\n|          fullScreenType           |       FullScreenType       | FullScreenType.rotateBox |                   Full screen type (rotate screen, or use RotateBox)                   |\n|     hideSystemBarOnFullScreen     |            bool            |           true           | Auto hide status bar on full screen, and show status bar on exit. (Extra desciption 1) |\n|           onFullScreen            |    void Function(bool)     |           null           |                 Callback on full screen. true is enter, false is exit.                 |\n\n**Extra desciption 1**:\nOn ios, you must add or edit a property:\n\n```xml\n\u003ckey\u003eUIViewControllerBasedStatusBarAppearance\u003c/key\u003e\n\u003ctrue/\u003e\n```\n\n### Build widget from IjkStatus\n\nBuild different widgets based on the current state.\n\n```dart\n\nWidget buildIjkPlayer() {\n  return IjkPlayer(\n    mediaController: mediaController,\n    stateWidgetBuilder: _buildStatusWidget,\n  );\n}\n\nWidget _buildStatusWidget(\n  BuildContext context,\n  IjkMediaController controller,\n  IjkStatus status,\n) {\n  if (status == IjkStatus.noDatasource) {\n    return Center(\n      child: Text(\n        \"no data\",\n        style: TextStyle(color: Colors.white),\n      ),\n    );\n  }\n\n  // you can custom your self status widget\n  return IjkStatusWidget.buildStatusWidget(context, controller, status);\n}\n```\n\n### Use Texture widget\n\nUse `textureBuilder` params to customize `Texture` widget, use `playerBuilder` in before 0.1.8 version.\n\nDefault use `buildDefaultIjkPlayer` method, params is `context,controller,videoInfo` and reture a `Widget`.\n\n```dart\nIJKPlayer(\n  mediaController: IjkMediaController(),\n  textureBuilder: (context,mediaController,videoInfo){\n    return Texture(); /// Your `Texture` widget\n  },\n);\n```\n\n## LICENSE\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcaijinglong%2Fflutter_ijkplayer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcaijinglong%2Fflutter_ijkplayer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcaijinglong%2Fflutter_ijkplayer/lists"}