[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-9304":3},{"id":4,"name":5,"fullName":6,"owner":5,"repo":5,"description":7,"homepage":8,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":16,"stars30d":17,"stars90d":15,"forks30d":15,"starsTrendScore":18,"compositeScore":19,"rankGlobal":9,"rankLanguage":9,"license":20,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":21,"hasPages":21,"topics":23,"createdAt":9,"pushedAt":9,"updatedAt":43,"readmeContent":44,"aiSummary":45,"trendingCount":15,"starSnapshotCount":15,"syncStatus":18,"lastSyncTime":46,"discoverSource":47},9304,"media-kit","media-kit\u002Fmedia-kit","A cross-platform video player & audio player for Flutter & Dart.","https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit",null,"Dart",1767,420,20,320,0,5,28,2,20.87,"MIT License",false,"main",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42],"android","audio","audio-player","c","cpp","dart","flutter","ios","java","libmpv","linux","macos","media-player","obj-c","swift","video","video-player","web","windows","2026-06-12 02:02:05","# [package:media_kit](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit)\n\n#### A cross-platform video player & audio player for Flutter & Dart.\n\n[![](https:\u002F\u002Fimg.shields.io\u002Fdiscord\u002F1079685977523617792?color=33cd57&label=Discord&logo=discord&logoColor=discord)](https:\u002F\u002Fdiscord.gg\u002Fh7qf2R9n57) [![Github Actions](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Factions\u002Fworkflows\u002Fci.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Factions\u002Fworkflows\u002Fci.yml)\n\n\u003Chr>\n\n\u003Cstrong>Sponsored with 💖 by\u003C\u002Fstrong>\n\n\u003Ca href=\"https:\u002F\u002Fgetstream.io\u002Fchat\u002Fsdk\u002Fflutter\u002F?utm_source=alexmercerind_dart&utm_medium=Github_Repo_Content_Ad&utm_content=Developer&utm_campaign=alexmercerind_December2022_FlutterSDK_klmh22\" target=\"_blank\">\n  \u003Cpicture>\n    \u003Csource media=\"(prefers-color-scheme: dark)\" srcset=\"https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F204903234-4a64b63c-2fc2-4eef-be44-d287d27021e5.svg\">\n    \u003Csource media=\"(prefers-color-scheme: light)\" srcset=\"https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F204903022-bbaa49ca-74c2-4a8f-a05d-af8314bfd2cc.svg\">\n    \u003Cimg alt=\"Stream Chat\" width=\"200\" height=\"auto\" src=\"https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F204903022-bbaa49ca-74c2-4a8f-a05d-af8314bfd2cc.svg\">\n  \u003C\u002Fpicture>\n\u003C\u002Fa>\n\u003Cbr>\u003C\u002Fbr>\n\u003Cstrong>\n  \u003Ca href=\"https:\u002F\u002Fgetstream.io\u002Fchat\u002Fsdk\u002Fflutter\u002F?utm_source=alexmercerind_dart&utm_medium=Github_Repo_Content_Ad&utm_content=Developer&utm_campaign=alexmercerind_December2022_FlutterSDK_klmh22\" target=\"_blank\">\n  Try the Flutter Chat tutorial\n  \u003C\u002Fa>\n\u003C\u002Fstrong>\n\n\u003Cbr>\u003C\u002Fbr>\n\n\u003Ca href=\"https:\u002F\u002Fottomatic.io\u002F\" target=\"_blank\">\n  \u003Cpicture>\n    \u003Csource media=\"(prefers-color-scheme: dark)\" srcset=\"https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F228648854-e5d7c557-ee92-47b2-a037-17b447873e1c.svg\">\n    \u003Csource media=\"(prefers-color-scheme: light)\" srcset=\"https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F228648844-f2a59ab1-12cd-4fee-bc8d-b2d332033c45.svg\">\n    \u003Cimg alt=\"Stream Chat\" width=\"200\" height=\"auto\" src=\"https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F228648844-f2a59ab1-12cd-4fee-bc8d-b2d332033c45.svg\">\n  \u003C\u002Fpicture>\n\u003C\u002Fa>\n\u003Cbr>\u003C\u002Fbr>\n\u003Cstrong>\n  \u003Ca href=\"https:\u002F\u002Fottomatic.io\u002F\" target=\"_blank\">\n  Clever Apps for Film Professionals\n  \u003C\u002Fa>\n\u003C\u002Fstrong>\n\n## Installation\n\n[package:media_kit](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit) is split into multiple packages to improve modularity & reduce bundle size.\n\n#### For apps that need video playback:\n\n```yaml\ndependencies:\n  media_kit: ^1.2.6 # Primary package.\n  media_kit_video: ^2.0.1 # For video rendering.\n  media_kit_libs_video: ^1.0.7 # Native video dependencies.\n```\n\n#### For apps that need audio playback:\n\n```yaml\ndependencies:\n  media_kit: ^1.2.6 # Primary package.\n  media_kit_libs_audio: ^1.0.7 # Native audio dependencies.\n```\n\n**Notes:**\n\n- The video libraries should be selected if both video & audio support is needed.\n- The `media_kit_libs_video` & `media_kit_libs_audio` packages should not be mixed.\n- The performance in [\"Release\" mode](https:\u002F\u002Fdocs.flutter.dev\u002Ftesting\u002Fbuild-modes#release) is substantially higher than in [\"Debug\" mode](https:\u002F\u002Fdocs.flutter.dev\u002Ftesting\u002Fbuild-modes#debug).\n- [Enable --split-per-abi](https:\u002F\u002Fdocs.flutter.dev\u002Fdeployment\u002Fandroid#what-is-a-fat-apk) or [use app bundle (instead of APK)](https:\u002F\u002Fdocs.flutter.dev\u002Fdeployment\u002Fandroid#when-should-i-build-app-bundles-versus-apks) on Android.\n\n## Platforms\n\n| Platform  | Video | Audio | Notes                              | Demo                                                                                                                        |\n| --------- | ----- | ----- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |\n| Android   | ✅    | ✅    | Android 5.0 or above.              | [Download](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Freleases\u002Fdownload\u002Fmedia_kit-v1.1.10\u002Fmedia_kit_test_android-arm64-v8a.apk) |\n| iOS       | ✅    | ✅    | iOS 9 or above.                    | [Download](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Freleases\u002Fdownload\u002Fmedia_kit-v1.1.10\u002Fmedia_kit_test_ios_arm64.7z)          |\n| macOS     | ✅    | ✅    | macOS 10.9 or above.               | [Download](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Freleases\u002Fdownload\u002Fmedia_kit-v1.1.10\u002Fmedia_kit_test_macos_universal.7z)    |\n| Windows   | ✅    | ✅    | Windows 7 or above.                | [Download](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Freleases\u002Fdownload\u002Fmedia_kit-v1.1.10\u002Fmedia_kit_test_win32_x64.7z)          |\n| GNU\u002FLinux | ✅    | ✅    | Any modern GNU\u002FLinux distribution. | [Download](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Freleases\u002Fdownload\u002Fmedia_kit-v1.1.10\u002Fmedia_kit_test_linux_x64.7z)          |\n| Web       | ✅    | ✅    | Any modern web browser.            | [Visit](https:\u002F\u002Fmedia-kit.github.io\u002Fmedia-kit\u002F)                                                                             |\n\n\u003Ctable>\n  \u003Ctr>\n    \u003Ctd>\n      Android\n    \u003C\u002Ftd>\n    \u003Ctd>\n      iOS\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n    \u003Ctd>\n      \u003Cimg src=\"https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Fassets\u002F28951144\u002Fcf93a1fd-e1d8-4d1c-8bd5-cc393cef1ce9\" height=\"400\" alt=\"Android\">\u003C\u002Fimg>\n      \u003Cimg src=\"https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Fassets\u002F28951144\u002Faea1f480-51e2-452a-b53c-c0e27f71f0d8\" height=\"400\" alt=\"Android\">\u003C\u002Fimg>\n    \u003C\u002Ftd>\n    \u003Ctd>\n      \u003Cimg src=\"https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Fassets\u002F28951144\u002Fe8ce64cb-1ea9-4a3e-bc9c-db620abf88c9\" height=\"400\" alt=\"iOS\">\u003C\u002Fimg>\n      \u003Cimg src=\"https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Fassets\u002F28951144\u002Fd7159df2-1df1-46d3-84f8-238e2a66bfbc\" height=\"400\" alt=\"iOS\">\u003C\u002Fimg>\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n    \u003Ctd>\n      macOS\n    \u003C\u002Ftd>\n    \u003Ctd>\n      Windows\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n    \u003Ctd>\n      \u003Cimg src=\"https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Fassets\u002F28951144\u002Ffca8dbbf-4262-431f-a04a-f3aa6afb2911\" height=\"200\" alt=\"macOS\">\u003C\u002Fimg>\n    \u003C\u002Ftd>\n    \u003Ctd>\n      \u003Cimg src=\"https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Fassets\u002F28951144\u002F742b0016-da58-42de-9880-ecaa0604c2b2\" height=\"200\" alt=\"Windows\">\u003C\u002Fimg>\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n    \u003Ctd>\n      GNU\u002FLinux\n    \u003C\u002Ftd>\n    \u003Ctd>\n      Web\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n    \u003Ctd>\n      \u003Cimg src=\"https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Fassets\u002F28951144\u002F8cd63750-6746-4c75-bc4e-cca5e4c61890\" height=\"200\" alt=\"GNU\u002FLinux\">\u003C\u002Fimg>\n    \u003C\u002Ftd>\n    \u003Ctd>\n      \u003Cimg src=\"https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Fassets\u002F28951144\u002Ffeb9fdf2-095f-43db-96af-f7782985238d\" height=\"200\" alt=\"Web\">\u003C\u002Fimg>\n    \u003C\u002Ftd>\n\u003C\u002Ftable>\n\n- ✅ Video playback\n- ✅ Audio playback\n- ✅ Cross platform\n- ✅ Wide format\u002Fcodec support\n- ✅ Hardware\u002FGPU acceleration\n- ✅ Playlist support with next\u002Fprevious\u002Fjump\u002Fshuffle\n- ✅ Volume\u002FRate\u002FPitch change\n- ✅ Video\u002FAudio\u002FSubtitle track selection\n- ✅ External audio\u002Fsubtitle track selection\n- ✅ HTTP headers\n- ✅ Video controls\n- ✅ Subtitle styling\n- ✅ Screenshot\n\n## TL;DR\n\nA quick usage example.\n\n```dart\nimport 'package:flutter\u002Fmaterial.dart';\n\n\u002F\u002F Make sure to add following packages to pubspec.yaml:\n\u002F\u002F * media_kit\n\u002F\u002F * media_kit_video\n\u002F\u002F * media_kit_libs_video\nimport 'package:media_kit\u002Fmedia_kit.dart';                      \u002F\u002F Provides [Player], [Media], [Playlist] etc.\nimport 'package:media_kit_video\u002Fmedia_kit_video.dart';          \u002F\u002F Provides [VideoController] & [Video] etc.\n\nvoid main() {\n  WidgetsFlutterBinding.ensureInitialized();\n  \u002F\u002F Necessary initialization for package:media_kit.\n  MediaKit.ensureInitialized();\n  runApp(\n    const MaterialApp(\n      home: MyScreen(),\n    ),\n  );\n}\n\nclass MyScreen extends StatefulWidget {\n  const MyScreen({Key? key}) : super(key: key);\n  @override\n  State\u003CMyScreen> createState() => MyScreenState();\n}\n\nclass MyScreenState extends State\u003CMyScreen> {\n  \u002F\u002F Create a [Player] to control playback.\n  late final player = Player();\n  \u002F\u002F Create a [VideoController] to handle video output from [Player].\n  late final controller = VideoController(player);\n\n  @override\n  void initState() {\n    super.initState();\n    \u002F\u002F Play a [Media] or [Playlist].\n    player.open(Media('https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F229373695-22f88f13-d18f-4288-9bf1-c3e078d83722.mp4'));\n  }\n\n  @override\n  void dispose() {\n    player.dispose();\n    super.dispose();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Center(\n      child: SizedBox(\n        width: MediaQuery.of(context).size.width,\n        height: MediaQuery.of(context).size.width * 9.0 \u002F 16.0,\n        \u002F\u002F Use [Video] widget to display video output.\n        child: Video(controller: controller),\n      ),\n    );\n  }\n}\n```\n\n**Note:** You may need to add required [permissions](#permissions) to your project (only if required).\n\n## Guide\n\nA usage guide for [package:media_kit](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit).\n\n**Tip:** Use \u003Ckbd>Ctrl\u003C\u002Fkbd> + \u003Ckbd>F\u003C\u002Fkbd> to quickly search for things.\n\n### Contents\n\n- [Initialization](#initialization)\n- [Create a `Player`](#create-a-player)\n- [Dispose a `Player`](#dispose-a-player)\n- [Open a `Media` or `Playlist`](#open-a-media-or-playlist)\n- [Play, pause or play\u002Fpause](#play-pause-or-playpause)\n- [Stop](#stop)\n- [Seek](#seek)\n- [Loop or repeat](#loop-or-repeat)\n- [Set volume, rate or pitch](#set-volume-rate-or-pitch)\n- [Handle playback events](#handle-playback-events)\n- [Shuffle the queue](#shuffle-the-queue)\n- [Use HTTP headers](#use-http-headers)\n- [Use `extras` to store additional data with `Media`](#use-extras-store-additional-data-with-media)\n- [Go to next, previous or any other position in queue](#go-to-next-previous-or-any-other-position-in-queue)\n- [Modify `Player`'s queue](#modify-players-queue)\n- [Select video, audio or subtitle track](#select-video-audio-or-subtitle-track)\n- [Select audio device](#select-audio-device)\n- [Display the video](#display-the-video)\n- [Capture screenshot](#capture-screenshot)\n- [Customize subtitles](#customize-subtitles)\n- [Load external subtitle track](#load-external-subtitle-track)\n- [Load external audio track](#load-external-audio-track)\n- [Video controls](#video-controls)\n- [Next steps](#next-steps)\n\n### Initialization\n\n`MediaKit.ensureInitialized` must be called before using the package:\n\n```dart\nvoid main() {\n  WidgetsFlutterBinding.ensureInitialized();\n  \u002F\u002F Make sure to add the required packages to pubspec.yaml:\n  \u002F\u002F * https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit#installation\n  \u002F\u002F * https:\u002F\u002Fpub.dev\u002Fpackages\u002Fmedia_kit#installation\n  MediaKit.ensureInitialized();\n  runApp(const MyApp());\n}\n```\n\nThe method also has some optional arguments to customize the global behavior. To handle any initialization errors, this may be surrounded by `try`\u002F`catch`.\n\n### Create a `Player`\n\nA `Player` instance is used to start & control the playback of a media source e.g. URL or file.\n\n```dart\nfinal Player player = Player();\n```\n\nAdditional options may be provided using the `configuration` argument in the constructor. In general situations, you will never require this.\n\n```dart\nfinal Player player = Player(\n  configuration: PlayerConfiguration(\n    \u002F\u002F Supply your options:\n    title: 'My awesome package:media_kit application',\n    ready: () {\n      print('The initialization is complete.');\n    },\n  ),\n);\n```\n\n### Dispose a `Player`\n\nIt is extremely important to release the allocated resources back to the system:\n\n```dart\nawait player.dispose();\n```\n\n### Open a `Media` or `Playlist`\n\nA `Playable` can either be a `Media` or a `Playlist`.\n\n- `Media`: Single playback source (file or URL).\n- `Playlist`: Queue of playback sources (file or URL).\n\nUse the `Player.open` method to load & start playback.\n\n#### `Media`\n\n```dart\nfinal playable = Media('https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F229373695-22f88f13-d18f-4288-9bf1-c3e078d83722.mp4');\nawait player.open(playable);\n```\n\n#### `Playlist`\n\n```dart\nfinal playable = Playlist(\n  [\n    Media('https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F229373695-22f88f13-d18f-4288-9bf1-c3e078d83722.mp4'),\n    Media('https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F229373709-603a7a89-2105-4e1b-a5a5-a6c3567c9a59.mp4'),\n    Media('https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F229373716-76da0a4e-225a-44e4-9ee7-3e9006dbc3e3.mp4'),\n    Media('https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F229373718-86ce5e1d-d195-45d5-baa6-ef94041d0b90.mp4'),\n    Media('https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F229373720-14d69157-1a56-4a78-a2f4-d7a134d7c3e9.mp4'),\n  ],\n);\nawait player.open(playable);\n```\n\n**Notes:**\n\n1. By default, this will automatically start playing the playable. This may be disabled as follows:\n\n```dart\nawait player.open(\n  playable,\n  play: false,\n);\n```\n\n2. By default, the playlist will start at the index `0`. This may be changed as follows:\n\n```dart\nfinal playable = Playlist(\n  [\n    Media('https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F229373695-22f88f13-d18f-4288-9bf1-c3e078d83722.mp4'),\n    Media('https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F229373709-603a7a89-2105-4e1b-a5a5-a6c3567c9a59.mp4'),\n    Media('https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F229373716-76da0a4e-225a-44e4-9ee7-3e9006dbc3e3.mp4'),\n    Media('https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F229373718-86ce5e1d-d195-45d5-baa6-ef94041d0b90.mp4'),\n    Media('https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F229373720-14d69157-1a56-4a78-a2f4-d7a134d7c3e9.mp4'),\n  ],\n  \u002F\u002F Declare the starting position.\n  index: 0,\n);\nawait player.open(playable);\n```\n\n### Play, pause or play\u002Fpause\n\nThe 3 methods are:\n\n```dart\nawait player.play();\n```\n\n```dart\nawait player.pause();\n```\n\n```dart\nawait player.playOrPause();\n```\n\n### Stop\n\nThe `stop` method may be used to stop the playback of currently opened `Media` or `Playlist`.\n\n```dart\nawait player.stop();\n```\n\nIt does not release allocated resources back to the system (unlike [`dispose`](#dispose-a-player)) & `Player` still stays usable.\n\n### Seek\n\nSupply the final position to `Player.seek` method as `Duration`:\n\n```dart\nawait player.seek(\n  const Duration(\n    minutes: 6,\n    seconds: 9,\n  ),\n);\n```\n\n### Loop or repeat\n\nThree `PlaylistMode`s are available:\n\n- `PlaylistMode.none`: End playback once end of the playlist is reached.\n- `PlaylistMode.single`: Indefinitely loop over the currently playing file in the playlist.\n- `PlaylistMode.loop`: Loop over the playlist & restart it from beginning once end is reached.\n\n```dart\nawait player.setPlaylistMode(PlaylistMode.single);\n```\n\n### Set volume, rate or pitch\n\n#### Set the volume\n\nThis controls the loudness of audio output. The maximum volume is `100.0`.\n\n```dart\nawait player.setVolume(50.0);\n```\n\n#### Set the rate\n\nThis controls the playback speed.\n\n```dart\nawait player.setRate(1.5);\n```\n\n#### Set the pitch\n\nThis controls the pitch of the audio output.\n\n```dart\nawait player.setPitch(1.2);\n```\n\n**Note:** This requires `pitch` argument to be `true` in `PlayerConfiguration`.\n\n### Handle playback events\n\nYou can access or subscribe to `Player`'s state changes.\n\nEvent handling is an extremely important part of media playback. It is used to show changes in the UI, handle errors, detect the occurrence of play\u002Fpause, end-of-file, position updates etc.\n\n- `Player.stream.*`: Provides access to `Player`'s state as [`Stream`](https:\u002F\u002Fdart.dev\u002Ftutorials\u002Flanguage\u002Fstreams)(s).\n- `Player.state.*`: Provides access to `Player`'s state directly (for instantaneous access).\n\nA typical example will be:\n\n```dart\nplayer.stream.playing.listen(\n  (bool playing) {\n    if (playing) {\n      \u002F\u002F Playing.\n    } else {\n      \u002F\u002F Paused.\n    }\n  },\n);\nplayer.stream.position.listen(\n  (Duration position) {\n    setState(() {\n      \u002F\u002F Update UI.\n    });\n  },\n);\n```\n\nThe following state(s) are available as events:\n\n| Type                        | Name           | Description                                                                                              |\n| --------------------------- | -------------- | -------------------------------------------------------------------------------------------------------- |\n| `Stream\u003CPlaylist>`          | `playlist`     | Currently opened media sources.                                                                          |\n| `Stream\u003Cbool>`              | `playing`      | Whether playing or not.                                                                                  |\n| `Stream\u003Cbool>`              | `completed`    | Whether end of currently playing media source has been reached.                                          |\n| `Stream\u003CDuration>`          | `position`     | Current playback position.                                                                               |\n| `Stream\u003CDuration>`          | `duration`     | Current playback duration.                                                                               |\n| `Stream\u003Cdouble>`            | `volume`       | Current volume.                                                                                          |\n| `Stream\u003Cdouble>`            | `rate`         | Current playback rate.                                                                                   |\n| `Stream\u003Cdouble>`            | `pitch`        | Current pitch.                                                                                           |\n| `Stream\u003Cbool>`              | `buffering`    | Whether buffering or not.                                                                                |\n| `Stream\u003CDuration>`          | `buffer`       | Current buffer position. This indicates how much of the stream has been decoded & cached by the demuxer. |\n| `Stream\u003CPlaylistMode>`      | `playlistMode` | Current playlist mode.                                                                                   |\n| `Stream\u003Cbool>`              | `shuffle`      | Whether playlist is shuffled or not.                                                                     |\n| `Stream\u003CAudioParams>`       | `audioParams`  | Audio parameters of the currently playing media source e.g. sample rate, channels, etc.                  |\n| `Stream\u003CVideoParams>`       | `videoParams`  | Video parameters of the currently playing media source e.g. width, height, rotation etc.                 |\n| `Stream\u003Cdouble?>`           | `audioBitrate` | Audio bitrate of the currently playing media source.                                                     |\n| `Stream\u003CAudioDevice>`       | `audioDevice`  | Currently selected audio device.                                                                         |\n| `Stream\u003CList\u003CAudioDevice>>` | `audioDevices` | Currently available audio devices.                                                                       |\n| `Stream\u003CTrack>`             | `track`        | Currently selected video, audio and subtitle track.                                                      |\n| `Stream\u003CTracks>`            | `tracks`       | Currently available video, audio and subtitle tracks.                                                    |\n| `Stream\u003Cint>`               | `width`        | Currently playing video's width.                                                                         |\n| `Stream\u003Cint>`               | `height`       | Currently playing video's height.                                                                        |\n| `Stream\u003Cint>`               | `subtitle`     | Currently displayed subtitle.                                                                            |\n| `Stream\u003CPlayerLog>`         | `log`          | Internal logs.                                                                                           |\n| `Stream\u003CString>`            | `error`        | Error messages. This may be used to handle & display errors to the user.                                 |\n\n### Shuffle the queue\n\nYou may find the requirement to shuffle the `Playlist` you `open`'d in `Player`, like some music players do.\n\n```dart\nawait player.setShuffle(true);\n```\n\n**Note:** This option is reset upon the next `Player.open` call.\n\n### Use HTTP headers\n\nDeclare the `httpHeaders` argument in `Media` constructor. It takes the HTTP headers as `Map\u003CString, String>`.\n\n```dart\nfinal playable = Media(\n  'https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F229373695-22f88f13-d18f-4288-9bf1-c3e078d83722.mp4',\n  httpHeaders: {\n    'Foo': 'Bar',\n    'Accept': '*\u002F*',\n    'Range': 'bytes=0-',\n  },\n);\n```\n\n### Use `extras` to store additional data with `Media`\n\nThe `extras` argument may be utilized to store additional data with a `Media` in form of `Map\u003CString, dynamic>`.\n\n```dart\nfinal playable = Media(\n  'https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F229373695-22f88f13-d18f-4288-9bf1-c3e078d83722.mp4',\n  extras: {\n    'track': '9',\n    'year': '2012',\n    'title': 'Courtesy Call',\n    'artist': 'Thousand Foot Krutch',\n    'album': 'The End Is Where We Begin',\n  },\n);\n```\n\n### Modify `Player`'s queue\n\nYou can add or remove (etc.) a `Media` in an already playing `Playlist`:\n\n#### Add\n\nAdd a new `Media` to the back of the queue:\n\n```dart\nawait player.add(Media('https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F229373695-22f88f13-d18f-4288-9bf1-c3e078d83722.mp4'));\n```\n\n#### Remove\n\nRemove any item from the queue:\n\n```dart\nawait player.remove(0);\n```\n\n#### Move\n\nMove any item in the queue from one position to another:\n\n```dart\nawait player.move(6, 9);\n```\n\n### Go to next, previous or any other position in queue\n\n#### Skip to the next queue item\n\n```dart\nawait player.next();\n```\n\n#### Skip to the previous queue item\n\n```dart\nawait player.previous();\n```\n\n#### Skip to any other queue item\n\n```dart\nawait player.jump(5);\n```\n\n### Select video, audio or subtitle track\n\nA media source may contain multiple video, audio or subtitle tracks e.g. for multiple languages. Available video, audio or subtitle tracks are notified through `Player`'s state. See [\"Handle playback events\" section](#handle-playback-events) for related information.\n\nBy default, video, audio & subtitle track is selected automatically _i.e._ `VideoTrack.auto()`, `AudioTrack.auto()` & `SubtitleTrack.auto()`.\n\n#### Automatic selection\n\n```dart\nawait player.setVideoTrack(VideoTrack.auto());\n\nawait player.setAudioTrack(AudioTrack.auto());\n\nawait player.setSubtitleTrack(SubtitleTrack.auto());\n```\n\n#### Disable track\n\nThis may be used to essentially disable video output, disable audio output or stop rendering of subtitles etc.\n\n```dart\nawait player.setVideoTrack(VideoTrack.no());\n\nawait player.setAudioTrack(AudioTrack.no());\n\nawait player.setSubtitleTrack(SubtitleTrack.no());\n```\n\n#### Select custom track\n\n- Retrieve currently available tracks:\n\n```dart\nList\u003CVideoTrack> videos = player.state.tracks.video;\nList\u003CAudioTrack> audios = player.state.tracks.audio;\nList\u003CSubtitleTrack> subtitles = player.state.tracks.subtitle;\n\n\u002F\u002F Get notified as [Stream]:\nplayer.stream.tracks.listen((event) {\n  List\u003CVideoTrack> videos = event.video;\n  List\u003CAudioTrack> audios = event.audio;\n  List\u003CSubtitleTrack> subtitles = event.subtitle;\n});\n```\n\n- Select the track:\n\n```dart\nawait player.setVideoTrack(videos[0]);\nawait player.setAudioTrack(audios[1]);\nawait player.setSubtitleTrack(subtitles[2]);\n```\n\n- Get notified about currently selected track:\n\n```dart\nVideoTrack video = player.state.track.video;\nAudioTrack audio = player.state.track.audio;\nSubtitleTrack subtitle = player.state.track.subtitle;\n\n\u002F\u002F Get notified as [Stream]:\nplayer.stream.track.listen((event) {\n  VideoTrack video = event.video;\n  AudioTrack audio = event.audio;\n  SubtitleTrack subtitle = event.subtitle;\n});\n```\n\n### Select audio device\n\nAvailable audio devices are notified through `Player`'s state. See [\"Handle playback events\" section](#handle-playback-events) for related information.\n\nBy default, audio device is selected automatically _i.e._ `AudioDevice.auto()`.\n\n#### Default selection\n\n```dart\nawait player.setAudioDevice(AudioDevice.auto());\n```\n\n#### Disable audio output\n\n```dart\nawait player.setAudioDevice(AudioDevice.no());\n```\n\n#### Select custom audio device\n\n- Retrieve currently available audio devices:\n\n```dart\nList\u003CAudioDevice> devices = player.state.audioDevices;\n\n\u002F\u002F Get notified as [Stream]:\nplayer.stream.audioDevices.listen((event) {\n  List\u003CAudioDevice> devices = event;\n});\n```\n\n- Select the audio device:\n\n```dart\nawait player.setAudioDevice(devices[1]);\n```\n\n- Get notified about currently selected audio device:\n\n```dart\nAudioDevice device = player.state.audioDevice;\n\n\u002F\u002F Get notified as [Stream]:\nplayer.stream.audioDevice.listen((event) {\n  AudioDevice device = event;\n});\n```\n\n### Display the video\n\nThe **existing [\"TL;DR example\"](#tldr) should provide you better idea**.\n\nFor displaying the video inside Flutter UI, you must:\n\n- Create `VideoController`\n  - Pass the `Player` you already have.\n- Create `Video` widget\n  - Pass the `VideoController` you already have.\n\nThe code is easier to understand:\n\n```dart\nclass _MyScreenState extends State\u003CMyScreen> {\n  late final Player player = Player();\n  late final VideoController controller = VideoController(player);\n\n  @override\n  void dispose() {\n    player.dispose();\n    super.dispose();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      body: Video(\n        controller: controller,\n      ),\n    );\n  }\n}\n```\n\nThe video playback uses [hardware acceleration](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FHardware_acceleration) _i.e._ GPU by default.\n\nAdditional options may be provided using the `configuration` argument in the constructor. In general situations, you will never require this.\n\n```dart\nfinal VideoController player = VideoController(\n  player,\n  configuration: const VideoControllerConfiguration(\n    \u002F\u002F Supply your options:\n    enableHardwareAcceleration: true,      \u002F\u002F default: true\n    width: 640,                            \u002F\u002F default: null\n    height: 480,                           \u002F\u002F default: null\n    \u002F\u002F The in-code comments is best place to know more about these options:\n    \u002F\u002F https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Fblob\u002Fmain\u002Fmedia_kit_video\u002Flib\u002Fsrc\u002Fvideo_controller\u002Fvideo_controller.dart\n  ),\n);\n```\n\n### Capture screenshot\n\nThe `screenshot` method takes the snapshot of the current video frame & returns encoded image bytes as `Uint8List`.\n\n```dart\nfinal Uint8List? screenshot = await player.screenshot();\n```\n\nAdditionally `format` argument may be specified to change the encoding format. Following formats are supported:\n\n- `image\u002Fjpeg`: Returns a JPEG encoded image.\n- `image\u002Fpng`: Returns a PNG encoded image.\n- `null`: Returns BGRA pixel buffer.\n\n### Customize subtitles\n\n`SubtitleViewConfiguration` can be passed to the `Video` widget for customizing the subtitles. The code is easier to understand:\n\nNotably, `TextStyle`, `TextAlign` & `EdgeInsetsGeometry` can be provided.\n\n```dart\nVideo(\n  controller: controller,\n  subtitleViewConfiguration: const SubtitleViewConfiguration(\n    style: TextStyle(\n      height: 1.4,\n      fontSize: 24.0,\n      letterSpacing: 0.0,\n      wordSpacing: 0.0,\n      color: Color(0xffffffff),\n      fontWeight: FontWeight.normal,\n      backgroundColor: Color(0xaa000000),\n    ),\n    textAlign: TextAlign.center,\n    padding: EdgeInsets.all(24.0),\n  ),\n);\n```\n\nhttps:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F253067794-73b5ca5d-e90d-4892-bc09-2a80f05c9f0b.mp4\n\n### Load external subtitle track\n\nThe `SubtitleTrack.uri` constructor can be used to load external subtitle track **with URI** e.g. SRT, WebVTT etc. The code is easier to understand:\n\n```dart\nawait player.setSubtitleTrack(\n  SubtitleTrack.uri(\n    'https:\u002F\u002Fwww.iandevlin.com\u002Fhtml5test\u002Fwebvtt\u002Fupc-video-subtitles-en.vtt',\n    title: 'English',\n    language: 'en',\n  ),\n);\n```\n\nThe `SubtitleTrack.data` constructor can be used to load external subtitle track **with data** e.g. SRT, WebVTT etc. The code is easier to understand:\n\n```dart\nplayer.setSubtitleTrack(\n  SubtitleTrack.data(\n    '''WEBVTT FILE\n\n1\n00:00:03.500 --> 00:00:05.000 D:vertical A:start\nEveryone wants the most from life\n\n2\n00:00:06.000 --> 00:00:09.000 A:start\nLike internet experiences that are rich \u003Cb>and\u003C\u002Fb> entertaining\n\n3\n00:00:11.000 --> 00:00:14.000 A:end\nPhone conversations where people truly \u003Cc.highlight>connect\u003C\u002Fc>\n\n4\n00:00:14.500 --> 00:00:18.000\nYour favourite TV programmes ready to watch at the touch of a button\n\n5\n00:00:19.000 --> 00:00:24.000\nWhich is why we are bringing TV, internet and phone together in \u003Cc.highlight>one\u003C\u002Fc> super package\n\n6\n00:00:24.500 --> 00:00:26.000\n\u003Cc.highlight>One\u003C\u002Fc> simple way to get everything\n\n7\n00:00:26.500 --> 00:00:27.500 L:12%\nUPC\n\n8\n00:00:28.000 --> 00:00:30.000 L:75%\nSimply for \u003Cu>everyone\u003C\u002Fu>\n''',\n    title: 'English',\n    language: 'en',\n  ),\n);\n```\n\n### Load external audio track\n\nThe `AudioTrack.uri` constructor can be used to load external audio track **with URI**. The code is easier to understand:\n\n```dart\nawait player.setAudioTrack(\n  AudioTrack.uri(\n    'https:\u002F\u002Fwww.iandevlin.com\u002Fhtml5test\u002Fwebvtt\u002Fv\u002Fupc-tobymanley.mp4',\n    title: 'English',\n    language: 'en',\n  ),\n);\n```\n\n### Video controls\n\n[`package:media_kit`](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit) provides highly-customizable pre-built video controls for usage.\n\nApart from theming, layout can be customized, position of buttons can be modified, custom buttons can be created etc. Necessary features like fullscreen, keyboard shortcuts & swipe-based controls are also supported by default.\n\n\u003Ctable>\n  \u003Ctr>\n    \u003Ctd>\n      \u003Ca href=\"#materialdesktopvideocontrols\">\u003Ctt>MaterialDesktopVideoControls\u003C\u002Ftt>\u003C\u002Fa>\n    \u003C\u002Ftd>\n    \u003Ctd>\n      \u003Ca href=\"#materialvideocontrols\">\u003Ctt>MaterialVideoControls\u003C\u002Ftt>\u003C\u002Fa>\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n    \u003Ctd>\n      \u003Cimg height=\"312\" src=\"https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F246606748-72557578-8be4-43c6-a3df-cb0aea99c879.jpg\">\n    \u003C\u002Ftd>\n    \u003Ctd>\n      \u003Cimg height=\"312\" src=\"https:\u002F\u002Fuser-images.githubusercontent.com\u002F28951144\u002F246650427-a5bbabad-6f7b-4098-9325-ebe2a3068720.jpg\">\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n\u003C\u002Ftable>\n\n- `Video` widget provides `controls` argument to display & customize video controls.\n- By default, [`AdaptiveVideoControls`](#adaptivevideocontrols) are used.\n\n#### Types\n\n| Type                                                            | Description                                                                                                                            |\n| --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |\n| [`AdaptiveVideoControls`](#adaptivevideocontrols)               | Selects [`MaterialVideoControls`](#materialvideocontrols), [`CupertinoVideoControls`](#cupertinovideocontrols) etc. based on platform. |\n| [`MaterialVideoControls`](#materialvideocontrols)               | [Material Design](https:\u002F\u002Fmaterial.io\u002F) video controls.                                                                                |\n| [`MaterialDesktopVideoControls`](#materialdesktopvideocontrols) | [Material Design](https:\u002F\u002Fmaterial.io\u002F) video controls for desktop.                                                                    |\n| [`CupertinoVideoControls`](#cupertinovideocontrols)             | [iOS-style](https:\u002F\u002Fdeveloper.apple.com\u002Fdesign\u002Fhuman-interface-guidelines\u002Fdesigning-for-ios) video controls.                           |\n| [`NoVideoControls`](#novideocontrols)                           | Disable video controls _i.e._ only render video output.                                                                                |\n| Custom                                                          | Provide custom `builder` for video controls.                                                                                           |\n\n#### Select existing video controls\n\nModify the `controls` argument. For advanced theming of existing video controls, see [theming & modifying video controls](#theming-&-modifying-video-controls) section.\n\n```dart\nScaffold(\n  body: Video(\n    controller: controller,\n    \u002F\u002F Select [MaterialVideoControls].\n    controls: MaterialVideoControls,\n  ),\n);\n```\n\n```dart\nScaffold(\n  body: Video(\n    controller: controller,\n    \u002F\u002F Select [CupertinoVideoControls].\n    controls: CupertinoVideoControls,\n  ),\n);\n```\n\n#### Build custom video controls\n\nPass custom builder `Widget Function(BuildContext, VideoController)` as `controls` argument.\n\n```dart\nScaffold(\n  body: Video(\n    controller: controller,\n    \u002F\u002F Provide custom builder for controls.\n    controls: (state) {\n      return Center(\n        child: IconButton(\n          onPressed: () {\n            state.widget.controller.player.playOrPause();\n          },\n          icon: StreamBuilder(\n            stream: state.widget.controller.player.stream.playing,\n            builder: (context, playing) => Icon(\n              playing.data == true ? Icons.pause : Icons.play_arrow,\n            ),\n          ),\n          \u002F\u002F It's not necessary to use [StreamBuilder] or to use [Player] & [VideoController] from [state].\n          \u002F\u002F [StreamSubscription]s can be made inside [initState] of this widget.\n        ),\n      );\n    },\n  ),\n);\n```\n\n#### Use & modify video controls\n\n##### `AdaptiveVideoControls`\n\n- Selects [`MaterialVideoControls`](#materialvideocontrols), [`CupertinoVideoControls`](#cupertinovideocontrols) etc. based on platform.\n- Theming:\n  - Theme the specific controls according to sections below.\n\n##### `MaterialVideoControls`\n\n- [Material Design](https:\u002F\u002Fmaterial.io\u002F) video controls.\n- Theming:\n  - Use `MaterialVideoControlsTheme` widget.\n  - `Video` widget(s) in the `child` tree will follow the specified theme:\n\n```dart\n\u002F\u002F Wrap [Video] widget with [MaterialVideoControlsTheme].\nMaterialVideoControlsTheme(\n  normal: MaterialVideoControlsThemeData(\n    \u002F\u002F Modify theme options:\n    buttonBarButtonSize: 24.0,\n    buttonBarButtonColor: Colors.white,\n    \u002F\u002F Modify top button bar:\n    topButtonBar: [\n      const Spacer(),\n      MaterialDesktopCustomButton(\n        onPressed: () {\n          debugPrint('Custom \"Settings\" button pressed.');\n        },\n        icon: const Icon(Icons.settings),\n      ),\n    ],\n  ),\n  fullscreen: const MaterialVideoControlsThemeData(\n    \u002F\u002F Modify theme options:\n    displaySeekBar: false,\n    automaticallyImplySkipNextButton: false,\n    automaticallyImplySkipPreviousButton: false,\n  ),\n  child: Scaffold(\n    body: Video(\n      controller: controller,\n    ),\n  ),\n);\n```\n\n- Related widgets (may be used in `primaryButtonBar`, `topButtonBar` & `bottomButtonBar`):\n  - `MaterialPlayOrPauseButton`\n  - `MaterialSkipNextButton`\n  - `MaterialSkipPreviousButton`\n  - `MaterialFullscreenButton`\n  - `MaterialCustomButton`\n  - `MaterialPositionIndicator`\n\n##### `MaterialDesktopVideoControls`\n\n- [Material Design](https:\u002F\u002Fmaterial.io\u002F) video controls for desktop.\n- Theming:\n  - Use `MaterialDesktopVideoControlsTheme` widget.\n  - `Video` widget(s) in the `child` tree will follow the specified theme:\n\n```dart\n\u002F\u002F Wrap [Video] widget with [MaterialDesktopVideoControlsTheme].\nMaterialDesktopVideoControlsTheme(\n  normal: MaterialDesktopVideoControlsThemeData(\n    \u002F\u002F Modify theme options:\n    seekBarThumbColor: Colors.blue,\n    seekBarPositionColor: Colors.blue,\n    toggleFullscreenOnDoublePress: false,\n    \u002F\u002F Modify top button bar:\n    topButtonBar: [\n      const Spacer(),\n      MaterialDesktopCustomButton(\n        onPressed: () {\n          debugPrint('Custom \"Settings\" button pressed.');\n        },\n        icon: const Icon(Icons.settings),\n      ),\n    ],\n    \u002F\u002F Modify bottom button bar:\n    bottomButtonBar: const [\n      Spacer(),\n      MaterialDesktopPlayOrPauseButton(),\n      Spacer(),\n    ],\n  ),\n  fullscreen: const MaterialDesktopVideoControlsThemeData(),\n  child: Scaffold(\n    body: Video(\n      controller: controller,\n    ),\n  ),\n);\n```\n\n- Related widgets (may be used in `primaryButtonBar`, `topButtonBar` & `bottomButtonBar`):\n  - `MaterialDesktopPlayOrPauseButton`\n  - `MaterialDesktopSkipNextButton`\n  - `MaterialDesktopSkipPreviousButton`\n  - `MaterialDesktopFullscreenButton`\n  - `MaterialDesktopCustomButton`\n  - `MaterialDesktopVolumeButton`\n  - `MaterialDesktopPositionIndicator`\n- Keyboard shortcuts may be modified using `keyboardShortcuts` argument. Default ones are listed below:\n\n| Shortcut                    | Action                |\n| --------------------------- | --------------------- |\n| Media Play Button           | Play                  |\n| Media Pause Button          | Pause                 |\n| Media Play\u002FPause Button     | Play\u002FPause            |\n| Media Next Track Button     | Skip Next             |\n| Media Previous Track Button | Skip Previous         |\n| Space                       | Play\u002FPause            |\n| J                           | Seek 10s Behind       |\n| I                           | Seek 10s Ahead        |\n| Arrow Left                  | Seek 2s Behind        |\n| Arrow Right                 | Seek 2s Ahead         |\n| Arrow Up                    | Increase Volume 5%    |\n| Arrow Down                  | Decrease Volume 5%    |\n| F                           | Enter\u002FExit Fullscreen |\n| Escape                      | Exit Fullscreen       |\n\n##### `CupertinoVideoControls`\n\n- [iOS-style](https:\u002F\u002Fdeveloper.apple.com\u002Fdesign\u002Fhuman-interface-guidelines\u002Fdesigning-for-ios) video controls.\n- Theming:\n  - Use `CupertinoVideoControlsTheme` widget.\n  - `Video` widget(s) in the `child` tree will follow the specified theme:\n\n```dart\n\u002F\u002F Wrap [Video] widget with [CupertinoVideoControlsTheme].\nCupertinoVideoControlsTheme(\n  normal: const CupertinoVideoControlsThemeData(\n    \u002F\u002F W.I.P.\n  ),\n  fullscreen: const CupertinoVideoControlsThemeData(\n    \u002F\u002F W.I.P.\n  ),\n  child: Scaffold(\n    body: Video(\n      controller: controller,\n    ),\n  ),\n);\n```\n\n##### `NoVideoControls`\n\n- Disable video controls _i.e._ only render video output.\n- Theming:\n  - No theming applicable.\n\n### Next steps\n\nThis guide follows a tutorial-like structure & covers nearly all features that [package:media_kit](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit) offers. However, it is _not complete_ by any means. You are free to improve this page & add more documentation, which newcomers may find helpful. The following places can help you learn more:\n\n- [API reference](https:\u002F\u002Fpub.dev\u002Fdocumentation\u002Fmedia_kit\u002Flatest\u002Fmedia_kit\u002Fmedia_kit-library.html) can be helpful for diving into deeper specifics.\n- [source-code of the demo application](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Ftree\u002Fmain\u002Fmedia_kit_test\u002Flib\u002Ftests) offers some complete code samples.\n- In-code comments & docstrings happen to be the most updated source of knowledge.\n\n## Goals\n\n[package:media_kit](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit) is a library for Flutter & Dart which **provides video & audio playback**.\n\n- **Strong:** Supports _most_ video & audio codecs.\n- **Performant:**\n  - Handles multiple FHD videos flawlessly.\n  - Rendering is GPU-powered (hardware accelerated).\n  - 4K \u002F 8K 60 FPS is supported.\n- **Stable:** Implementation is well-tested & used across number of intensive media playback related apps.\n- **Feature Proof:** A simple usage API while offering a large number of features to target multitude of apps.\n- **Modular:** Project is split into a number of packages for reducing bundle size.\n- **Cross Platform**: Implementation works on all platforms supported by Flutter & Dart:\n  - Android\n  - iOS\n  - macOS\n  - Windows\n  - GNU\u002FLinux\n  - Web\n- **Flexible Architecture:**\n  - Major part of implementation (80%+) is in 100% Dart ([FFI](https:\u002F\u002Fdart.dev\u002Fguides\u002Flibraries\u002Fc-interop)) & shared across platforms.\n    - Makes the behavior of library same & more predictable across platforms.\n    - Makes development & implementation of new features easier & faster.\n    - Avoids separate maintenance of native implementation for each platform.\n  - Only video embedding code is platform-specific & part of separate package.\n\nYou may see project's [architecture](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit#architecture) & [implementation](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit#implementation) details for further information.\n\nThe project aims to meet demands of the community, this includes:\n\n1. Holding accountability.\n2. Ensuring timely maintenance.\n\n## Supported Formats\n\nA wide variety of formats & codecs are supported. Complete list may be found below:\n\n\u003Cdetails>\n\n```\n3dostr          3DO STR\n4xm             4X Technologies\naa              Audible AA format files\naac             raw ADTS AAC (Advanced Audio Coding)\naax             CRI AAX\nac3             raw AC-3\nace             tri-Ace Audio Container\nacm             Interplay ACM\nact             ACT Voice file format\nadf             Artworx Data Format\nadp             ADP\nads             Sony PS2 ADS\nadx             CRI ADX\naea             MD STUDIO audio\nafc             AFC\naiff            Audio IFF\naix             CRI AIX\nalaw            PCM A-law\nalias_pix       Alias\u002FWavefront PIX image\nalp             LEGO Racers ALP\namr             3GPP AMR\namrnb           raw AMR-NB\namrwb           raw AMR-WB\nanm             Deluxe Paint Animation\napac            raw APAC\napc             CRYO APC\nape             Monkey's Audio\napm             Ubisoft Rayman 2 APM\napng            Animated Portable Network Graphics\naptx            raw aptX\naptx_hd         raw aptX HD\naqtitle         AQTitle subtitles\nargo_asf        Argonaut Games ASF\nargo_brp        Argonaut Games BRP\nargo_cvg        Argonaut Games CVG\nasf             ASF (Advanced \u002F Active Streaming Format)\nasf_o           ASF (Advanced \u002F Active Streaming Format)\nass             SSA (SubStation Alpha) subtitle\nast             AST (Audio Stream)\nau              Sun AU\nav1             AV1 Annex B\navi             AVI (Audio Video Interleaved)\navr             AVR (Audio Visual Research)\navs             Argonaut Games Creature Shock\navs2            raw AVS2-P2\u002FIEEE1857.4\navs3            raw AVS3-P2\u002FIEEE1857.10\nbethsoftvid     Bethesda Softworks VID\nbfi             Brute Force & Ignorance\nbfstm           BFSTM (Binary Cafe Stream)\nbin             Binary text\nbink            Bink\nbinka           Bink Audio\nbit             G.729 BIT file format\nbitpacked       Bitpacked\nbmp_pipe        piped bmp sequence\nbmv             Discworld II BMV\nboa             Black Ops Audio\nbonk            raw Bonk\nbrender_pix     BRender PIX image\nbrstm           BRSTM (Binary Revolution Stream)\nc93             Interplay C93\ncaf             Apple CAF (Core Audio Format)\ncavsvideo       raw Chinese AVS (Audio Video Standard)\ncdg             CD Graphics\ncdxl            Commodore CDXL video\ncine            Phantom Cine\ncodec2          codec2 .c2 demuxer\ncodec2raw       raw codec2 demuxer\nconcat          Virtual concatenation script\ncri_pipe        piped cri sequence\ndash            Dynamic Adaptive Streaming over HTTP\ndata            raw data\ndaud            D-Cinema audio\ndcstr           Sega DC STR\ndds_pipe        piped dds sequence\nderf            Xilam DERF\ndfa             Chronomaster DFA\ndfpwm           raw DFPWM1a\ndhav            Video DAV\ndirac           raw Dirac\ndnxhd           raw DNxHD (SMPTE VC-3)\ndpx_pipe        piped dpx sequence\ndsf             DSD Stream File (DSF)\ndshow           DirectShow capture\ndsicin          Delphine Software International CIN\ndss             Digital Speech Standard (DSS)\ndts             raw DTS\ndtshd           raw DTS-HD\ndv              DV (Digital Video)\ndvbsub          raw dvbsub\ndvbtxt          dvbtxt\ndxa             DXA\nea              Electronic Arts Multimedia\nea_cdata        Electronic Arts cdata\neac3            raw E-AC-3\nepaf            Ensoniq Paris Audio File\nexr_pipe        piped exr sequence\nf32be           PCM 32-bit floating-point big-endian\nf32le           PCM 32-bit floating-point little-endian\nf64be           PCM 64-bit floating-point big-endian\nf64le           PCM 64-bit floating-point little-endian\nffmetadata      FFmpeg metadata in text\nfilm_cpk        Sega FILM \u002F CPK\nfilmstrip       Adobe Filmstrip\nfits            Flexible Image Transport System\nflac            raw FLAC\nflic            FLI\u002FFLC\u002FFLX animation\nflv             FLV (Flash Video)\nfrm             Megalux Frame\nfsb             FMOD Sample Bank\nfwse            Capcom's MT Framework sound\ng722            raw G.722\ng723_1          G.723.1\ng726            raw big-endian G.726 (\"left aligned\")\ng726le          raw little-endian G.726 (\"right aligned\")\ng729            G.729 raw format demuxer\ngdigrab         GDI API Windows frame grabber\ngdv             Gremlin Digital Video\ngem_pipe        piped gem sequence\ngenh            GENeric Header\ngif             CompuServe Graphics Interchange Format (GIF)\ngif_pipe        piped gif sequence\ngsm             raw GSM\ngxf             GXF (General eXchange Format)\nh261            raw H.261\nh263            raw H.263\nh264            raw H.264 video\nhca             CRI HCA\nhcom            Macintosh HCOM\nhdr_pipe        piped hdr sequence\nhevc            raw HEVC video\nhls             Apple HTTP Live Streaming\nhnm             Cryo HNM v4\nico             Microsoft Windows ICO\nidcin           id Cinematic\nidf             iCE Draw File\niff             IFF (Interchange File Format)\nifv             IFV CCTV DVR\nilbc            iLBC storage\nimage2          image2 sequence\nimage2pipe      piped image2 sequence\nimf             IMF (Interoperable Master Format)\ningenient       raw Ingenient MJPEG\nipmovie         Interplay MVE\nipu             raw IPU Video\nircam           Berkeley\u002FIRCAM\u002FCARL Sound Format\niss             Funcom ISS\niv8             IndigoVision 8000 video\nivf             On2 IVF\nivr             IVR (Internet Video Recording)\nj2k_pipe        piped j2k sequence\njacosub         JACOsub subtitle format\njpeg_pipe       piped jpeg sequence\njpegls_pipe     piped jpegls sequence\njpegxl_pipe     piped jpegxl sequence\njv              Bitmap Brothers JV\nkux             KUX (YouKu)\nkvag            Simon & Schuster Interactive VAG\nlaf             LAF (Limitless Audio Format)\nlavfi           Libavfilter virtual input device\nlive_flv        live RTMP FLV (Flash Video)\nlmlm4           raw lmlm4\nloas            LOAS AudioSyncStream\nlrc             LRC lyrics\nluodat          Video CCTV DAT\nlvf             LVF\nlxf             VR native stream (LXF)\nm4v             raw MPEG-4 video\nmatroska,webm   Matroska \u002F WebM\nmca             MCA Audio Format\nmcc             MacCaption\nmgsts           Metal Gear Solid: The Twin Snakes\nmicrodvd        MicroDVD subtitle format\nmjpeg           raw MJPEG video\nmjpeg_2000      raw MJPEG 2000 video\nmlp             raw MLP\nmlv             Magic Lantern Video (MLV)\nmm              American Laser Games MM\nmmf             Yamaha SMAF\nmods            MobiClip MODS\nmoflex          MobiClip MOFLEX\nmov,mp4,m4a,3gp,3g2,mj2 QuickTime \u002F MOV\nmp3             MP2\u002F3 (MPEG audio layer 2\u002F3)\nmpc             Musepack\nmpc8            Musepack SV8\nmpeg            MPEG-PS (MPEG-2 Program Stream)\nmpegts          MPEG-TS (MPEG-2 Transport Stream)\nmpegtsraw       raw MPEG-TS (MPEG-2 Transport Stream)\nmpegvideo       raw MPEG video\nmpjpeg          MIME multipart JPEG\nmpl2            MPL2 subtitles\nmpsub           MPlayer subtitles\nmsf             Sony PS3 MSF\nmsnwctcp        MSN TCP Webcam stream\nmsp             Microsoft Paint (MSP))\nmtaf            Konami PS2 MTAF\nmtv             MTV\nmulaw           PCM mu-law\nmusx            Eurocom MUSX\nmv              Silicon Graphics Movie\nmvi             Motion Pixels MVI\nmxf             MXF (Material eXchange Format)\nmxg             MxPEG clip\nnc              NC camera feed\nnistsphere      NIST SPeech HEader REsources\nnsp             Computerized Speech Lab NSP\nnsv             Nullsoft Streaming Video\nnut             NUT\nnuv             NuppelVideo\nobu             AV1 low overhead OBU\nogg             Ogg\noma             Sony OpenMG audio\npaf             Amazing Studio Packed Animation File\npam_pipe        piped pam sequence\npbm_pipe        piped pbm sequence\npcx_pipe        piped pcx sequence\npfm_pipe        piped pfm sequence\npgm_pipe        piped pgm sequence\npgmyuv_pipe     piped pgmyuv sequence\npgx_pipe        piped pgx sequence\nphm_pipe        piped phm sequence\nphotocd_pipe    piped photocd sequence\npictor_pipe     piped pictor sequence\npjs             PJS (Phoenix Japanimation Society) subtitles\npmp             Playstation Portable PMP\npng_pipe        piped png sequence\npp_bnk          Pro Pinball Series Soundbank\nppm_pipe        piped ppm sequence\npsd_pipe        piped psd sequence\npsxstr          Sony Playstation STR\npva             TechnoTrend PVA\npvf             PVF (Portable Voice Format)\nqcp             QCP\nqdraw_pipe      piped qdraw sequence\nqoi_pipe        piped qoi sequence\nr3d             REDCODE R3D\nrawvideo        raw video\nrealtext        RealText subtitle format\nredspark        RedSpark\nrka             RKA (RK Audio)\nrl2             RL2\nrm              RealMedia\nroq             id RoQ\nrpl             RPL \u002F ARMovie\nrsd             GameCube RSD\nrso             Lego Mindstorms RSO\nrtp             RTP input\nrtsp            RTSP input\ns16be           PCM signed 16-bit big-endian\ns16le           PCM signed 16-bit little-endian\ns24be           PCM signed 24-bit big-endian\ns24le           PCM signed 24-bit little-endian\ns32be           PCM signed 32-bit big-endian\ns32le           PCM signed 32-bit little-endian\ns337m           SMPTE 337M\ns8              PCM signed 8-bit\nsami            SAMI subtitle format\nsap             SAP input\nsbc             raw SBC (low-complexity subband codec)\nsbg             SBaGen binaural beats script\nscc             Scenarist Closed Captions\nscd             Square Enix SCD\nsdns            Xbox SDNS\nsdp             SDP\nsdr2            SDR2\nsds             MIDI Sample Dump Standard\nsdx             Sample Dump eXchange\nser             SER (Simple uncompressed video format for astronomical capturing)\nsga             Digital Pictures SGA\nsgi_pipe        piped sgi sequence\nshn             raw Shorten\nsiff            Beam Software SIFF\nsimbiosis_imx   Simbiosis Interactive IMX\nsln             Asterisk raw pcm\nsmjpeg          Loki SDL MJPEG\nsmk             Smacker\nsmush           LucasArts Smush\nsol             Sierra SOL\nsox             SoX native\nspdif           IEC 61937 (compressed data in S\u002FPDIF)\nsrt             SubRip subtitle\nstl             Spruce subtitle format\nsubviewer       SubViewer subtitle format\nsubviewer1      SubViewer v1 subtitle format\nsunrast_pipe    piped sunrast sequence\nsup             raw HDMV Presentation Graphic Stream subtitles\nsvag            Konami PS2 SVAG\nsvg_pipe        piped svg sequence\nsvs             Square SVS\nswf             SWF (ShockWave Flash)\ntak             raw TAK\ntedcaptions     TED Talks captions\nthp             THP\ntiertexseq      Tiertex Limited SEQ\ntiff_pipe       piped tiff sequence\ntmv             8088flex TMV\ntruehd          raw TrueHD\ntta             TTA (True Audio)\ntty             Tele-typewriter\ntxd             Renderware TeXture Dictionary\nty              TiVo TY Stream\nu16be           PCM unsigned 16-bit big-endian\nu16le           PCM unsigned 16-bit little-endian\nu24be           PCM unsigned 24-bit big-endian\nu24le           PCM unsigned 24-bit little-endian\nu32be           PCM unsigned 32-bit big-endian\nu32le           PCM unsigned 32-bit little-endian\nu8              PCM unsigned 8-bit\nv210            Uncompressed 4:2:2 10-bit\nv210x           Uncompressed 4:2:2 10-bit\nvag             Sony PS2 VAG\nvbn_pipe        piped vbn sequence\nvc1             raw VC-1\nvc1test         VC-1 test bitstream\nvfwcap          VfW video capture\nvidc            PCM Archimedes VIDC\nvividas         Vividas VIV\nvivo            Vivo\nvmd             Sierra VMD\nvobsub          VobSub subtitle format\nvoc             Creative Voice\nvpk             Sony PS2 VPK\nvplayer         VPlayer subtitles\nvqf             Nippon Telegraph and Telephone Corporation (NTT) TwinVQ\nw64             Sony Wave64\nwady            Marble WADY\nwav             WAV \u002F WAVE (Waveform Audio)\nwavarc          Waveform Archiver\nwc3movie        Wing Commander III movie\nwebm_dash_manifest WebM DASH Manifest\nwebp_pipe       piped webp sequence\nwebvtt          WebVTT subtitle\nwsaud           Westwood Studios audio\nwsd             Wideband Single-bit Data (WSD)\nwsvqa           Westwood Studios VQA\nwtv             Windows Television (WTV)\nwv              WavPack\nwve             Psion 3 audio\nxa              Maxis XA\nxbin            eXtended BINary text (XBIN)\nxbm_pipe        piped xbm sequence\nxmd             Konami XMD\nxmv             Microsoft XMV\nxpm_pipe        piped xpm sequence\nxvag            Sony PS3 XVAG\nxwd_pipe        piped xwd sequence\nxwma            Microsoft xWMA\nyop             Psygnosis YOP\nyuv4mpegpipe    YUV4MPEG pipe\n```\n\n\u003C\u002Fdetails>\n\n**Notes:**\n\n- The list contains the supported formats (& not containers).\n  - A video\u002Faudio format may be present in a number of containers.\n  - e.g. an MP4 file generally contains H264 video stream.\n- On the web, format support depends upon the web browser.\n  - It happens to be extremely limited as compared to native platforms.\n\n## Permissions\n\nYou may need to declare & request internet access or file-system permissions depending upon platform.\n\n### Android\n\nEdit `android\u002Fapp\u002Fsrc\u002Fmain\u002FAndroidManifest.xml` to add the following permissions inside `\u003Cmanifest>` tag:\n\n```xml\n\u003Cmanifest xmlns:android=\"http:\u002F\u002Fschemas.android.com\u002Fapk\u002Fres\u002Fandroid\" package=\"com.example.app\">\n    \u003Capplication\n      ...\n      \u002F>\n    \u003C\u002Fapplication>\n    \u003C!--\n      Internet access permissions.\n      -->\n    \u003Cuses-permission android:name=\"android.permission.INTERNET\" \u002F>\n    \u003C!--\n      Media access permissions.\n      Android 13 or higher.\n      https:\u002F\u002Fdeveloper.android.com\u002Fabout\u002Fversions\u002F13\u002Fbehavior-changes-13#granular-media-permissions\n      -->\n    \u003Cuses-permission android:name=\"android.permission.READ_MEDIA_AUDIO\" \u002F>\n    \u003Cuses-permission android:name=\"android.permission.READ_MEDIA_VIDEO\" \u002F>\n    \u003C!--\n      Storage access permissions.\n      Android 12 or lower.\n      -->\n    \u003Cuses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" \u002F>\n    \u003Cuses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" \u002F>\n\u003C\u002Fmanifest>\n```\n\nUse [`package:permission_handler`](https:\u002F\u002Fpub.dev\u002Fpackages\u002Fpermission_handler) to request access at runtime:\n\n```dart\nif (\u002F* Android 13 or higher. *\u002F) {\n  \u002F\u002F Video permissions.\n  if (await Permission.videos.isDenied || await Permission.videos.isPermanentlyDenied) {\n    final state = await Permission.videos.request();\n    if (!state.isGranted) {\n      await SystemNavigator.pop();\n    }\n  }\n  \u002F\u002F Audio permissions.\n  if (await Permission.audio.isDenied || await Permission.audio.isPermanentlyDenied) {\n    final state = await Permission.audio.request();\n    if (!state.isGranted) {\n      await SystemNavigator.pop();\n    }\n  }\n} else {\n  if (await Permission.storage.isDenied || await Permission.storage.isPermanentlyDenied) {\n    final state = await Permission.storage.request();\n    if (!state.isGranted) {\n      await SystemNavigator.pop();\n    }\n  }\n}\n```\n\n### iOS\n\nEdit `ios\u002FRunner\u002FInfo-Release.plist`, `ios\u002FRunner\u002FInfo-Profile.plist`, `ios\u002FRunner\u002FInfo-Debug.plist`:\n\n**Enable internet access**\n\n```xml\n\u003Ckey>NSAppTransportSecurity\u003C\u002Fkey>\n\u003Cdict>\n    \u003Ckey>NSAllowsArbitraryLoads\u003C\u002Fkey>\n    \u003Ctrue\u002F>\n\u003C\u002Fdict>\n```\n\n### Windows\n\nN\u002FA\n\n### macOS\n\nEdit `macos\u002FRunner\u002FRelease.entitlements` & `macos\u002FRunner\u002FDebugProfile.entitlements`:\n\n**Enable internet access**\n\n```xml\n\u003Ckey>com.apple.security.network.client\u003C\u002Fkey>\n\u003Ctrue\u002F>\n```\n\n**Disable sand-box to access files**\n\n```xml\n\u003Ckey>com.apple.security.app-sandbox\u003C\u002Fkey>\n\u003Cfalse\u002F>\n```\n\n### GNU\u002FLinux\n\nN\u002FA\n\n### Web\n\nN\u002FA\n\n## Notes\n\n### Android\n\nN\u002FA\n\n### iOS\n\nN\u002FA\n\n### Windows\n\nN\u002FA\n\n### macOS\n\nDuring the build phase, the following warnings are not critical and cannot be silenced:\n\n```log\n#import \"Headers\u002Fmedia_kit_video-Swift.h\"\n        ^\n\u002Fpath\u002Fto\u002Fmedia_kit\u002Fmedia_kit_test\u002Fbuild\u002Fmacos\u002FBuild\u002FProducts\u002FDebug\u002Fmedia_kit_video\u002Fmedia_kit_video.framework\u002FHeaders\u002Fmedia_kit_video-Swift.h:270:31: warning: 'objc_ownership' only applies to Objective-C object or block pointer types; type here is 'CVPixelBufferRef' (aka 'struct __CVBuffer *')\n- (CVPixelBufferRef _Nullable __unsafe_unretained)copyPixelBuffer SWIFT_WARN_UNUSED_RESULT;\n```\n\n```log\n# 1 \"\u003Ccommand line>\" 1\n ^\n\u003Ccommand line>:20:9: warning: 'POD_CONFIGURATION_DEBUG' macro redefined\n#define POD_CONFIGURATION_DEBUG 1 DEBUG=1\n        ^\n#define POD_CONFIGURATION_DEBUG 1\n        ^\n```\n\n### GNU\u002FLinux\n\n#### Install libmpv\n\nSystem shared libraries from distribution specific user-installed packages are used by-default. **This is how GNU\u002FLinux works.** You can install these as follows:\n\n##### Ubuntu\u002FDebian\n\n```bash\nsudo apt install libmpv-dev mpv\n```\n\n##### Packaging\n\nThere are other ways to bundle these within your app package e.g. within Snap or Flatpak. Few examples:\n\n- [Celluloid](https:\u002F\u002Fgithub.com\u002Fcelluloid-player\u002Fcelluloid\u002Fblob\u002Fmaster\u002Fflatpak\u002Fio.github.celluloid_player.Celluloid.json)\n- [VidCutter](https:\u002F\u002Fgithub.com\u002Fozmartian\u002Fvidcutter\u002Ftree\u002Fmaster\u002F_packaging)\n\n#### Utilize [mimalloc](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fmimalloc)\n\nYou should consider replacing the default memory allocator with [mimalloc](https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fmimalloc) for [avoiding memory leaks](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Fissues\u002F68).\n\nThis is as simple as [adding one line to `linux\u002FCMakeLists.txt`](https:\u002F\u002Fgithub.com\u002Fmedia-kit\u002Fmedia-kit\u002Fblob\u002Fd02a97ce70b316207db024401fb99e3f4509a250\u002Fmedia_kit_test\u002Flinux\u002FCMakeLists.txt#L92-L94):\n\n```cmake\ntarget_link_libraries(${BINARY_NAME} PRIVATE ${MIMALLOC_LIB})\n```\n\nIn case you prefer dynamic linking of mimalloc, you can additionally add the following line to your `linux\u002FCMakeLists.txt`:\n\n```cmake\n# use dynamically linked mimalloc\nset(MIMALLOC_USE_STATIC_LIBS OFF)\n```\n\nIn this case, please ensure you install `libmimalloc-dev` at compile time and `libmimalloc2.0` as runtime dependencies.\n\n#### Ubuntu\u002FDebian\n\n```bash\nsudo apt install libmimalloc-dev libmimalloc2.0\n```\n\n### Web\n\nOn the web, **libmpv is not used**. Video & audio playback is handled by embedding [HTML `\u003Cvideo>` element](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FHTML\u002FElement\u002Fvideo). The format support depends upon the web browser. It happens to be extremely limited as compared to native platforms.\n\n## Architecture\n\n### package:media_kit\n\n_Click on the zoom button on top-right or pinch inside._\n\n```mermaid\n%%{\n  init: {\n    'themeVariables': {\n      'fontFamily': 'BlinkMacSystemFont, Segoe UI, Noto Sans, Helvetica, Arial, Apple Color Emoji, Segoe UI Emoji'\n    }\n  }\n}%%\nclassDiagram\n\n  Player *-- PlatformPlayer\n  PlatformPlayer \u003C|-- NativePlayer\n  PlatformPlayer \u003C|-- WebPlayer\n  PlatformPlayer *-- PlayerState\n  PlatformPlayer *-- PlayerStream\n  PlatformPlayer o-- PlayerConfiguration\n\n  NativePlayer \u003C.. NativeLibrary\n  NativePlayer \u003C.. Initializer\n\n  Playable \u003C.. Media\n  Playable \u003C.. Playlist\n\n  class Initializer {\n    +create(path: String, callback: Function, options: Map\u003CString, String>): Future\u003CPointer\u003Cmpv_handle>>\n    +dispose(handle: Pointer\u003Cmpv_handle>)\n  }\n\n  class Playable {\n  }\n\n  class AudioDevice {\n  }\n\n  class Media {\n    +String uri\n    +dynamic extras\n  }\n\n  class Playlist {\n    +List\u003CMedia> medias\n    +index index\n  }\n\n  class PlayerStream {\n    +Stream\u003CPlaylist> playlist\n    +Stream\u003Cbool> playing\n    +Stream\u003Cbool> completed\n    +Stream\u003CDuration> position\n    +Stream\u003CDuration> duration\n    +Stream\u003CDuration> buffer\n    +Stream\u003Cdouble> volume\n    +Stream\u003Cdouble> rate\n    +Stream\u003Cdouble> pitch\n    +Stream\u003Cbool> buffering\n    +Stream\u003CDuration> buffer\n    +Stream\u003CAudioParams> audioParams\n    +Stream\u003CVideoParams> videoParams\n    +Stream\u003Cdouble?> audioBitrate\n    +Stream\u003CAudioDevice> audioDevice\n    +Stream\u003CList\u003CAudioDevice>> audioDevices\n    +Stream\u003CTrack> track\n    +Stream\u003CTracks> tracks\n    +Stream\u003Cint> width\n    +Stream\u003Cint> height\n    +Stream\u003CList\u003CString>> subtitle\n    +Stream\u003CPlayerLog> log\n    +Stream\u003CString> error\n  }\n\n  class PlayerState {\n    +Playlist playlist\n    +bool playing\n    +bool completed\n    +Duration position\n    +Duration duration\n    +Duration buffer\n    +double volume\n    +double rate\n    +double pitch\n    +bool buffering\n    +Duration buffer\n    +AudioParams audioParams\n    +VideoParams videoParams\n    +double? audioBitrate\n    +AudioDevice audioDevice\n    +List\u003CAudioDevice audioDevices\n    +Track track\n    +Tracks tracks\n    +int width\n    +int height\n    +List\u003CString> subtitle\n  }\n\n  class Player {\n    +PlatformPlayer? platform\n\n    +«get» PlayerState state\n    +«get» PlayerStream stream\n\n    +dispose()\n    +open(playable: Playable)\n    +play()\n    +stop()\n    +pause()\n    +playOrPause()\n    +add(media: Media)\n    +remove(index: int)\n    +next()\n    +previous()\n    +jump(index: int)\n    +move(from: int, to: int)\n    +seek(duration: Duration)\n    +setPlaylistMode(playlistMode: PlaylistMode)\n    +setVolume(volume: double)\n    +setRate(rate: double)\n    +setPitch(pitch: double)\n    +setShuffle(bool: double)\n    +setAudioDevice(device: AudioDevice)\n    +setVideoTrack(track: VideoTrack)\n    +setAudioTrack(track: AudioTrack)\n    +setSubtitleTrack(track: SubtitleTrack)\n    +screenshot(): Uint8List\n  }\n\n  class PlatformPlayer {\n    +PlayerState state\n    +PlayerStream stream\n    +PlayerConfiguration configuration\n\n    +dispose()*\n    +open(playable: Playable)*\n    +play()*\n    +stop()*\n    +pause()*\n    +playOrPause()*\n    +add(media: Media)*\n    +remove(index: int)*\n    +next()*\n    +previous()*\n    +jump(index: int)*\n    +move(from: int, to: int)*\n    +seek(duration: Duration)*\n    +setPlaylistMode(playlistMode: PlaylistMode)*\n    +setVolume(volume: double)*\n    +setRate(rate: double)*\n    +setPitch(pitch: double)*\n    +setShuffle(bool: double)*\n    +setAudioDevice(device: AudioDevice)*\n    +setVideoTrack(track: VideoTrack)*\n    +setAudioTrack(track: AudioTrack)*\n    +setSubtitleTrack(track: SubtitleTrack)*\n    +screenshot(): Uint8List*\n\n    +«get» handle: Future\u003Cint>*\n\n    #StreamController\u003CPlaylist> playlistController\n    #StreamController\u003Cbool> playingController\n    #StreamController\u003Cbool> completedController\n    #StreamController\u003CDuration> positionController\n    #StreamController\u003CDuration> durationController\n    #StreamController\u003CDuration> bufferController\n    #StreamController\u003Cdouble> volumeController\n    #StreamController\u003Cdouble> rateController\n    #StreamController\u003Cdouble> pitchController\n    #StreamController\u003Cbool> bufferingController\n    #StreamController\u003CPlayerLog> logController\n    #StreamController\u003CPlayerError> errorController\n    #StreamController\u003CAudioParams> audioParamsController\n    #StreamController\u003Cdouble?> audioBitrateController\n    #StreamController\u003CAudioDevice> audioDeviceController\n    #StreamController\u003CList\u003CAudioDevice>> audioDevicesController\n    #StreamController\u003CTrack> trackController\n    #StreamController\u003CTracks> tracksController\n    #StreamController\u003Cint> widthController\n    #StreamController\u003Cint> heightController\n  }\n\n  class NativePlayer {\n    +dispose()\n    +open(playable: Playable)\n    +play()\n    +stop()\n    +pause()\n    +playOrPause()\n    +add(media: Media)\n    +remove(index: int)\n    +next()\n    +previous()\n    +jump(index: int)\n    +move(from: int, to: int)\n    +seek(duration: Duration)\n    +setPlaylistMode(playlistMode: PlaylistMode)\n    +setVolume(volume: double)\n    +setRate(rate: double)\n    +setPitch(pitch: double)\n    +setShuffle(bool: double)\n    +setAudioDevice(device: AudioDevice)\n    +setVideoTrack(track: VideoTrack)\n    +setAudioTrack(track: AudioTrack)\n    +setSubtitleTrack(track: SubtitleTrack)\n    +screenshot(): Uint8List\n\n    +«get» handle: Future\u003Cint>\n  }\n\n  class WebPlayer {\n    +dispose()\n    +open(playable: Playable)\n    +play()\n    +stop()\n    +pause()\n    +playOrPause()\n    +add(media: Media)\n    +remove(index: int)\n    +next()\n    +previous()\n    +jump(index: int)\n    +move(from: int, to: int)\n    +seek(duration: Duration)\n    +setPlaylistMode(playlistMode: PlaylistMode)\n    +setVolume(volume: double)\n    +setRate(rate: double)\n    +setPitch(pitch: double)\n    +setShuffle(bool: double)\n    +setAudioDevice(device: AudioDevice)\n    +setVideoTrack(track: VideoTrack)\n    +setAudioTrack(track: AudioTrack)\n    +setSubtitleTrack(track: SubtitleTrack)\n    +screenshot(): Uint8List\n\n    +«get» handle: Future\u003Cint>\n  }\n\n  class NativeLibrary {\n    +find()$ String?\n  }\n```\n\n### package:media_kit_video\n\n_Click on the zoom button on top-right or pinch inside._\n\n#### Android\n\n```mermaid\n%%{\n  init: {\n    'themeVariables': {\n      'fontFamily': 'BlinkMacSystemFont, Segoe UI, Noto Sans, Helvetica, Arial, Apple Color Emoji, Segoe UI Emoji'\n    }\n  }\n}%%\nclassDiagram\n\n  MediaKitVideoPlugin \"1\" *-- \"1\" VideoOutputManager: Create VideoOutput(s) with VideoOutputManager for handle passed through platform channel\n  VideoOutputManager \"1\" *-- \"*\" VideoOutput: Create VideoOutput(s) to send back id & wid for render. Dispose to release.\n  VideoOutput \u003C.. MediaKitAndroidHelper: Create & dispose JNI global object reference to android.view.Surface (for --wid)\n\n  class MediaKitVideoPlugin {\n    -MethodChannel channel\n    -VideoOutputManager videoOutputManager\n  }\n\n  class VideoOutputManager {\n    -HashMap\u003CLong, VideoOutput> videoOutputs\n    -TextureRegistry textureRegistryReference\n    -Object lock\n\n    +create(handle: long, textureUpdateCallback: TextureUpdateCallback)\n    +dispose(handle: long)\n    +setSurfaceSize(handle: long, width: int, height: int): long\n  }\n\n  class VideoOutput {\n    $Method newGlobalObjectRef\n    $Method deleteGlobalObjectRef\n    $Handler handler\n\n    -long id\n    -long wid\n\n    -TextureUpdateCallback textureUpdateCallback\n    -TextureRegistry.SurfaceProducer surfaceProducer\n\n    -long handle\n    -MethodChannel channelReference\n    -TextureRegistry textureRegis","media-kit\u002Fmedia-kit 是一个为 Flutter 和 Dart 设计的跨平台音视频播放器。它通过模块化设计减少了应用包体积，同时支持 Android、iOS、Linux、macOS 以及 Windows 等多个操作系统。项目使用 Dart 语言编写，并基于 libmpv 实现了高性能的多媒体解码与播放功能。适合需要在多种设备上提供一致媒体体验的应用场景，如在线教育、娱乐应用等。MIT 许可证下开源，社区活跃，拥有超过1700个星标和400多次分叉。","2026-06-11 03:22:05","top_language"]