{"id":17937759,"url":"https://github.com/apivideo/api.video-player-sdk","last_synced_at":"2025-08-25T00:36:36.996Z","repository":{"id":39877330,"uuid":"266742841","full_name":"apivideo/api.video-player-sdk","owner":"apivideo","description":"SDK to control and interact with the api.video HTML5 Player","archived":false,"fork":false,"pushed_at":"2025-01-29T08:28:52.000Z","size":508,"stargazers_count":50,"open_issues_count":2,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-24T08:55:35.993Z","etag":null,"topics":["javascript","playback","player","sdk","sdk-js","video","video-player"],"latest_commit_sha":null,"homepage":"https://api.video","language":"TypeScript","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/apivideo.png","metadata":{"files":{"readme":"README.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-05-25T09:49:30.000Z","updated_at":"2025-01-29T08:28:55.000Z","dependencies_parsed_at":"2023-01-30T01:01:01.447Z","dependency_job_id":"33757dde-9594-42c0-8b1c-abf9962d5873","html_url":"https://github.com/apivideo/api.video-player-sdk","commit_stats":{"total_commits":86,"total_committers":9,"mean_commits":9.555555555555555,"dds":"0.34883720930232553","last_synced_commit":"351282522bf414457730800116b0302ccd20ff4e"},"previous_names":["apivideo/player-sdk"],"tags_count":31,"template":false,"template_full_name":null,"purl":"pkg:github/apivideo/api.video-player-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apivideo%2Fapi.video-player-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apivideo%2Fapi.video-player-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apivideo%2Fapi.video-player-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apivideo%2Fapi.video-player-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apivideo","download_url":"https://codeload.github.com/apivideo/api.video-player-sdk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apivideo%2Fapi.video-player-sdk/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261640819,"owners_count":23188419,"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":["javascript","playback","player","sdk","sdk-js","video","video-player"],"created_at":"2024-10-28T23:07:31.340Z","updated_at":"2025-07-01T18:03:16.997Z","avatar_url":"https://github.com/apivideo.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!--\u003cdocumentation_excluded\u003e--\u003e\n\n[![badge](https://img.shields.io/twitter/follow/api_video?style=social)](https://twitter.com/intent/follow?screen_name=api_video) \u0026nbsp; [![badge](https://img.shields.io/github/stars/apivideo/api.video-player-sdk?style=social)](https://github.com/apivideo/api.video-player-sdk) \u0026nbsp; [![badge](https://img.shields.io/discourse/topics?server=https%3A%2F%2Fcommunity.api.video)](https://community.api.video)\n![](https://github.com/apivideo/.github/blob/main/assets/apivideo_banner.png)\n\n\u003ch1 align=\"center\"\u003eapi.video player SDK\u003c/h1\u003e\n\n[api.video](https://api.video) is the video infrastructure for product builders. Lightning fast video APIs for integrating, scaling, and managing on-demand \u0026 low latency live streaming features in your app.\n\n## Table of contents\n\n- [Table of contents](#table-of-contents)\n- [Project description](#project-description)\n- [Getting started](#getting-started)\n  - [Installation](#installation)\n    - [Method #1: requirejs](#method-1-requirejs)\n    - [Method #2: typescript](#method-2-typescript)\n    - [Method #2: simple include in a javascript project](#method-2-simple-include-in-a-javascript-project)\n- [Documentation](#documentation)\n  - [Instantiation](#instantiation)\n    - [Ads](#ads)\n  - [Methods](#methods)\n  - [Full example](#full-example)\n  - [Control an existing embedded player using the SDK](#control-an-existing-embedded-player-using-the-sdk)\n\n\u003c!--\u003c/documentation_excluded\u003e--\u003e\n\u003c!--\u003cdocumentation_only\u003e\n---\ntitle: api.video Player SDK\nmeta:\ndescription: The official api.video Player SDK for api.video. [api.video](https://api.video/) is the video infrastructure for product builders. Lightning fast video APIs for integrating, scaling, and managing on-demand \u0026 low latency live streaming features in your app.\n---\n\n# api.video Player SDK\n\n[api.video](https://api.video/) is the video infrastructure for product builders. Lightning fast video APIs for integrating, scaling, and managing on-demand \u0026 low latency live streaming features in your app.\n\n\u003c/documentation_only\u003e--\u003e\n\n## Project description\n\nSDK to control and interact with the api.video HTML5 Player\n\n## Getting started\n\n### Installation\n\n#### Method #1: requirejs\n\nIf you use requirejs you can add the SDK as a dependency to your project with\n\n```sh\n$ npm install --save @api.video/player-sdk\n```\n\nYou can then use the SDK in your script:\n\n```javascript\nvar { PlayerSdk } = require(\"@api.video/player-sdk\");\n\nvar sdk = new PlayerSdk(\"#target\", {\n  id: \"\u003cVIDEO_ID\u003e\",\n  // ... other optional options\n});\n```\n\n#### Method #2: typescript\n\nIf you use Typescript you can add the SDK as a dependency to your project with\n\n```sh\n$ npm install --save @api.video/player-sdk\n```\n\nYou can then use the SDK in your script:\n\n```typescript\nimport { PlayerSdk } from \"@api.video/player-sdk\";\n\nconst sdk = new PlayerSdk(\"#target\", {\n  id: \"\u003cVIDEO_ID\u003e\",\n  // ... other optional options\n});\n```\n\n#### Method #2: simple include in a javascript project\n\nInclude the SDK in your HTML file like so:\n\n```html\n\u003chead\u003e\n  ...\n  \u003cscript src=\"https://unpkg.com/@api.video/player-sdk\" defer\u003e\u003c/script\u003e\n\u003c/head\u003e\n```\n\nThen, once the `window.onload` event has been triggered, create your player using `new PlayerSdk()`:\n\n```html\n\u003cscript type=\"text/javascript\"\u003e\n  window.player = new PlayerSdk(\"#target\", {\n    id: \"\u003cVIDEO_ID\u003e\",\n    // ... other optional options\n  });\n\u003c/script\u003e\n```\n\n## Documentation\n\n### Instantiation\n\nThe PlayerSdk constructor takes 2 parameters:\n\n- `targetSelector: string | Element` a CSS selector targeting the DOM element in which you want to create the player (eg. \"#target\"), or the DOM element itself\n- `options: SdkOptions` an object containing the player options. The available options are the following:\n\n|    Option name | Mandatory             | Type                           | Description                                                                                                                                       |\n| -------------: | --------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |\n|             id | **yes**               | string                         | the id of the video (videoId or liveStreamId)                                                                                                     |\n|          token | yes for private video | string                         | the [private video](https://api.video/blog/tutorials/tutorial-private-videos/) url token                                                          |\n| privateSession | no                    | string                         | the [private video](https://api.video/blog/tutorials/tutorial-private-videos/) session id if needed                                               |\n|           live | no (default: false)   | boolean                        | indicate that the video is a live one                                                                                                             |\n|       autoplay | no (default: false)   | boolean                        | start playing the video as soon as it is loaded                                                                                                   |\n|          muted | no (default: false)   | boolean                        | the video is muted                                                                                                                                |\n|       metadata | no (default: empty)   | object                         | object containing [metadata](https://api.video/blog/tutorials/dynamic-metadata/) (see **Full example** below)                                     |\n|   hideControls | no (default: false)   | boolean                        | the controls are hidden (except unmute button if the video starts muted)                                                                          |\n|     chromeless | no (default: false)   | boolean                        | chromeless mode: all controls are hidden                                                                                                          |\n|      hideTitle | no (default: false)   | boolean                        | the video title is hidden                                                                                                                         |\n|     hidePoster | no (default: false)   | boolean                        | the poster image isn't displayed                                                                                                                  |\n|  showSubtitles | no (default: false)   | boolean                        | the video subtitles are shown by default                                                                                                          |\n|           loop | no (default: false)   | boolean                        | once the video is finished it automatically starts again                                                                                          |\n|   playbackRate | no (default: 1)       | number                         | the playback rate of the video: 1 for normal, 2 for x2, etc.                                                                                      |\n|       sequence | no                    | `{start: number, end: number}` | define a sequence of the video to play. The video will start at the `start` timecode and end at the `end` timecode. The timecodes are in seconds. |\n|            ads | no                    | `{adTagUrl: string}`           | see below [ads](#ads)                                                                                                                             |\n|   customDomain | no                    | string                         | if you've enabled Custom Domains for your account, the complete 'embed' domain (eg. embed.mydomain.com)                                           |\n|        hotkeys | no (default: true)    | boolean                        | if false, deactivate the player's hotkeys to prevent it from capturing focus, which can be beneficial in certain scenarios                        |\n\nThe sdk instance can be used to control the video playback, and to listen to player events.\n\n#### Ads\n\nAds can be displayed in the player. To do so, you need to pass the `ads` option to the sdk constructor. In the `ads` object, pass the `adTagUrl` property with the url of the ad tag. The ad tag must be a VAST 2.0 or 3.0 url. For more information about VAST, check the [IAB documentation](https://www.iab.com/guidelines/vast/).\n\nNote: ads are displayed using the [Google IMA SDK](https://developers.google.com/interactive-media-ads/docs/sdks/html5/quickstart).\n\n### Methods\n\nThe sdk instance has the following methods:\n\n**`loadConfig(options: SdkOptions)`**\n\nLoad a new video in the same instance of the player. Available options are the same as the ones passed to the SDK constructor (see available).\n\n\u003e Example:\n\n```javascript\nplayer.loadConfig({\n  id: \"\u003cVIDEO_ID\u003e\",\n  hideTitle: true,\n  hideControls: true,\n});\n```\n\n**`play()`**\n\nStart playing the video.\n\n**`pause()`**\n\nPause the video playback.\n\n**`mute()`**\n\nMute the video.\n\n**`unmute()`**\n\nUnmute the video.\n\n**`hideControls(controls?: ControlName[])`**\n\nHide the player controls.\n\n`controls` parameter type definition:\n\n```typescript\ntype ControlName =\n  | \"play\"\n  | \"seekBackward\"\n  | \"seekForward\"\n  | \"playbackRate\"\n  | \"volume\"\n  | \"fullscreen\"\n  | \"subtitles\"\n  | \"chapters\"\n  | \"pictureInPicture\"\n  | \"progressBar\"\n  | \"chromecast\"\n  | \"download\"\n  | \"more\";\n```\n\n\u003e If no value is provided for the \"controls\" parameter, all controls will be hidden.\n\n**Note**: the only control that can still be visible is the unmute button if the video as started muted. To hide all controls, including this one, use the setChromeless() method\n\nExample:\n\n```javascript\nplayer.hideControls();\n```\n\n\u003e If a list of control names if provided, the associated controls will be hidden.\n\nExample:\n\n```javascript\nplayer.showControls(); // display all controls ...\nplayer.hideControls([\"download\", \"subtitles\"]); // ... except \"download\" and \"subtitles\"\n```\n\n**`showControls(controls?: ControlName[])`**\n\nShow the player controls.\n\n`controls` parameter type definition:\n\n```typescript\ntype ControlName =\n  | \"play\"\n  | \"seekBackward\"\n  | \"seekForward\"\n  | \"playbackRate\"\n  | \"volume\"\n  | \"fullscreen\"\n  | \"subtitles\"\n  | \"chapters\"\n  | \"pictureInPicture\"\n  | \"progressBar\"\n  | \"chromecast\"\n  | \"download\"\n  | \"more\";\n```\n\n\u003e If no value is provided for the \"controls\" parameter, all controls will be displayed.\n\nExample:\n\n```javascript\nplayer.showControls();\n```\n\n\u003e If a list of control names if provided, the associated controls will be displayed.\n\nExample:\n\n```javascript\nplayer.hideControls(); // hide all controls ...\nplayer.showControls([\"download\", \"subtitles\"]); // ... except \"download\" and \"subtitles\" ...\n// ...\nplayer.showControls([\"progressBar\"]); // ... and the progress bar\n```\n\n**`setChromeless(chromeless: boolean)`**\n\nDefine if the player should be in chromeless mode (all controls hidden).\n\n**`hideSubtitles()`**\n\nHide the player subtitles.\n\n**`showSubtitles()`**\n\nShow the player subtitles.\n\n**`hideTitles()`**\n\nHide the video title at the top of the video.\n\n**`showTitles()`**\n\nShow the video title at the top of the video.\n\n**`setLoop(loop: boolean)`**\n\nDefine if the video should be played in loop.\n\n**`setAutoplay(autoplay: boolean)`**\n\nDefine if the video should start playing as soon as it is loaded\n\n**`seek(time: number)`**\n\nAdd/substract the given number of seconds to/from the playback time.\n\n**`setPlaybackRate(rate: number)`**\n\nSet the current playback rate.\n\nExample:\n\n```javascript\nplayer.setPlaybackRate(2); // Play at 2x rate\n```\n\n**`setCurrentTime(time: number)`**\n\nSet the current playback time (seconds).\n\n\u003e Example:\n\n```javascript\nplayer.setCurrentTime(24); // Go the 24th second\n```\n\n**`setVolume(volume: number)`**\n\nChange the audio volume to the given value. From 0 to 1 (0 = muted, 1 = 100%).\n\n\u003e Example:\n\n```javascript\nplayer.setVolume(0.75); // Set the volume to 75%\n```\n\n**`setVideoStyleObjectFit(value: \"contain\" | \"cover\" | \"fill\" | \"none\" | \"scale-down\")`**\n\nChange the [object-fit](https://developer.mozilla.org/fr/docs/Web/CSS/object-fit) CSS value of the video tag.\n\nExample:\n\n```javascript\nplayer.setVideoStyleObjectFit(\"cover\"); // Set the object-fit to cover\n```\n\n**`setVideoStyleTransform(value: string)`**\n\nChange the [transform](https://developer.mozilla.org/fr/docs/Web/CSS/transform) CSS value of the video tag.\n\nExample:\n\n```javascript\nplayer.setVideoStyleTransform(\"rotateY(180deg)\"); // Apply a 180deg rotation around the Y axis (mirroring)\n```\n\n**`setTheme(theme: PlayerTheme)`**\n\nChange the appearance of the player.\n\n`theme` parameter type definition:\n\n```typescript\ntype PlayerTheme = {\n  text?: string;\n  link?: string;\n  linkHover?: string;\n  trackPlayed?: string;\n  trackUnplayed?: string;\n  trackBackground?: string;\n  backgroundTop?: string;\n  backgroundBottom?: string;\n  backgroundText?: string;\n  linkActive?: string;\n};\n```\n\n\u003e Example:\n\n```javascript\nplayer.setTheme({\n  link: \"red\",\n  linkHover: \"rgba(0, 255, 0, 1)\",\n  backgroundBottom: \"#0000ff\",\n});\n```\n\n**`requestFullscreen()`**\n\nRequest fullscreen mode (this may not work in some cases depending on browser restrictions)\n\n**`exitFullscreen()`**\n\nLeave fullscreen mode\n\n**`requestPictureInPicture()`**\n\nRequest picture in picture mode (this may not work in some cases depending on browser restrictions)\n\n**`exitPictureInPicture()`**\n\nLeave picture in picture mode\n\n**`getPaused(callback?: (paused: boolean) =\u003e void): Promise\u003cboolean\u003e`**\n\nCheck weither the video is paused.\n\n**`getPlaying(callback?: (playing: boolean) =\u003e void): Promise\u003cboolean\u003e`**\n\nCheck weither the video is playing.\n\n**`getMuted(callback?: (muted: boolean) =\u003e void): Promise\u003cboolean\u003e`**\n\nCheck weither the video is muted.\n\n**`getDuration(callback?: (duration: number) =\u003e void): Promise\u003cnumber\u003e`**\n\nRetrieve the duration of the video.\n\n**`getCurrentTime(callback?: (currentTime: number) =\u003e void): Promise\u003cnumber\u003e`**\n\nRetrieve the current playback time of the video.\n\n**`getVolume(callback?: (volume: number) =\u003e void): Promise\u003cnumber\u003e`**\n\nRetrieve the current volume.\n\n**`getLoop(callback?: (loop: boolean) =\u003e void): Promise\u003cboolean\u003e`**\n\nCheck whether the video is in loop mode.\n\n**`getPlaybackRate(callback?: (rate: number) =\u003e void): Promise\u003cnumber\u003e`**\n\nRetrieve the playback rate.\n\n**`isLiveStream(callback?: (live: boolean) =\u003e void): Promise\u003cboolean\u003e`**\n\nCheck whether the video is a live stream.\n\n**`download(filename?: string): void`**\n\nDownload the video. If a filename is not provided, the default name 'video.mp4' will be used.\nAn exception will be thrown if the video cannot be downloaded.\n\n**`destroy()`**\n\nDestroy the player instance.\n\n**`addEventListener(event: string, callback: () =\u003e void)`**\n\nDefine a callback function that will be called when the given event is triggered by the player.\n\nAvailable events are the following:\n\n|             Event name | Description                                                                | Parameter                                           |\n| ---------------------: | -------------------------------------------------------------------------- | --------------------------------------------------- |\n|       airplayConnected | Started to play on an airplay device                                       | -                                                   |\n|    airplayDisconnected | Stopped to play on an airplay device                                       | -                                                   |\n|    chromecastConnected | Started to play on a chromecast device                                     | -                                                   |\n| chromecastDisconnected | Stopped to play on a chromecast device                                     | -                                                   |\n|       controlsdisabled | Controls are now disabled                                                  | -                                                   |\n|        controlsenabled | Controls are now enabled                                                   | -                                                   |\n|                  ended | The playback as reached the ended of the video                             | -                                                   |\n|                  error | An error occured                                                           | -                                                   |\n|              firstplay | The video started to play for the first time                               | -                                                   |\n|       fullscreenchange | The player goes to (or goes back from) full screen                         | `{ isFullScreen: boolean }`                         |\n|             mouseenter | The user's mouse entered the player area                                   | -                                                   |\n|             mouseleave | The user's mouse leaved the player area                                    | -                                                   |\n|                  pause | The video has been paused                                                  | -                                                   |\n|                   play | The video started to play (for the first time or after having been paused) | -                                                   |\n|           playerresize | The player size has changed                                                | -                                                   |\n|          qualitychange | The video quality has changed                                              | `{ resolution: { height: number, width: number } }` |\n|             ratechange | The playback rate has changed                                              | -                                                   |\n|                  ready | The player is ready to play                                                | -                                                   |\n|                 resize | The video size has changed                                                 |\n|                seeking | The player is seeking                                                      | -                                                   |\n|             timeupdate | The playback time has changed                                              | `{ currentTime: number }`                           |\n|             useractive | The user is active                                                         | -                                                   |\n|           userinactive | The user is inactive                                                       | -                                                   |\n|           volumechange | The volume has changed                                                     | `{ volume: number }`                                |\n\nExamples:\n\n```javascript\n// listen to the 'play' event\nplayer.addEventListener(\"play\", function () {\n  console.log(\"play event received\");\n});\n\nplayer.addEventListener(\"qualitychange\", function (ev) {\n  console.log(\n    `quality has changed: ${ev.resolution.width}x${ev.resolution.height}`\n  );\n});\n```\n\n### Full example\n\n```html\n\u003chtml\u003e\n  \u003chead\u003e\n    ...\n    \u003cscript src=\"/index.js\" defer\u003e\u003c/script\u003e\n  \u003c/head\u003e\n\n  \u003cbody\u003e\n    \u003cdiv id=\"target\"\u003e\u003c/div\u003e\n\n    \u003c!-- buttons that call player methods to control the video playback --\u003e\n    \u003cbutton onclick=\"javascript:player.play()\" id=\"play-btn\"\u003eplay\u003c/button\u003e\n    \u003cbutton onclick=\"javascript:player.pause()\" id=\"pause-btn\" disabled\u003e\n      pause\n    \u003c/button\u003e\n    \u003cbutton onclick=\"javascript:player.mute()\"\u003emute\u003c/button\u003e\n    \u003cbutton onclick=\"javascript:player.unmute()\"\u003eunmute\u003c/button\u003e\n  \u003c/body\u003e\n\n  \u003cscript type=\"text/javascript\"\u003e\n    window.onload = function () {\n      // create the player in the #target element\n      window.player = new PlayerSdk(\"#target\", {\n        id: \"123456\",\n        metadata: {\n          dogcat: \"dog\",\n        },\n      });\n\n      // when the 'play' event is received, disable the 'play' button and enable the 'pause' button\n      player.addEventListener(\"play\", function () {\n        document.getElementById(\"play-btn\").disabled = true;\n        document.getElementById(\"pause-btn\").disabled = false;\n      });\n\n      // when the 'pause' event is received, disable the 'pause' button and enable the 'play' button\n      player.addEventListener(\"pause\", function () {\n        document.getElementById(\"play-btn\").disabled = false;\n        document.getElementById(\"pause-btn\").disabled = true;\n      });\n    };\n  \u003c/script\u003e\n\u003c/html\u003e\n```\n\n### Control an existing embedded player using the SDK\n\nIt's also possible to integrate the SDK in a page that already contains an embedded player in order to control it and to listen to its events. Let's consider the following page :\n\n```html\n\u003chtml\u003e\n  \u003chead\u003e\n    ...\n  \u003c/head\u003e\n\n  \u003cbody\u003e\n    ...\n    \u003c!-- my embedded player --\u003e\n    \u003ciframe\n      src=\"//embed.api.video/vod/vi54sj9dAakOHJXKrUycCQZp\"\n      width=\"100%\"\n      height=\"100%\"\n      frameborder=\"0\"\n      allowfullscreen\n    \u003e\u003c/iframe\u003e\n    ...\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\nTo attach the SDK to this player, you'll have to make the following changed in your page:\n\n- import the `sdk.js` script in your page,\n- create a `PlayerSdk` instance once the page is loaded.\n\nHere is how the page will look like with these changes :\n\n```html\n\u003chtml\u003e\n  \u003chead\u003e\n    ...\n    \u003cscript src=\"/index.js\" defer\u003e\u003c/script\u003e\n  \u003c/head\u003e\n\n  \u003cbody\u003e\n    ...\n    \u003c!-- my embedded player --\u003e\n    \u003ciframe\n      id=\"myPlayer\"\n      src=\"//embed.api.video/vod/vi54sj9dAakOHJXKrUycCQZp\"\n      width=\"100%\"\n      height=\"100%\"\n      frameborder=\"0\"\n      allowfullscreen\n    \u003e\u003c/iframe\u003e\n    ...\n  \u003c/body\u003e\n\n  \u003cscript type=\"text/javascript\"\u003e\n    window.onload = function () {\n      // attach the sdk to the existing player\n      window.player = new PlayerSdk(\"#myPlayer\");\n\n      // window.player can now be used to control the player as described above\n    };\n  \u003c/script\u003e\n\u003c/html\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapivideo%2Fapi.video-player-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapivideo%2Fapi.video-player-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapivideo%2Fapi.video-player-sdk/lists"}