{"id":13735868,"url":"https://github.com/openplayerjs/openplayerjs","last_synced_at":"2026-03-07T17:11:57.407Z","repository":{"id":37734870,"uuid":"147235939","full_name":"openplayerjs/openplayerjs","owner":"openplayerjs","description":"Lightweight HTML5 video/audio player with smooth controls and ability to play VAST/VPAID/VMAP ads","archived":false,"fork":false,"pushed_at":"2026-03-03T22:37:59.000Z","size":16963,"stargazers_count":621,"open_issues_count":2,"forks_count":89,"subscribers_count":10,"default_branch":"master","last_synced_at":"2026-03-04T03:43:09.166Z","etag":null,"topics":["audio","dash","hls","html5","html5-audio","html5-video","html5-video-player","javascript","openplayerjs","player","typescript","vast","video"],"latest_commit_sha":null,"homepage":"https://www.openplayerjs.com","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/openplayerjs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-09-03T17:41:25.000Z","updated_at":"2026-02-25T03:23:19.000Z","dependencies_parsed_at":"2023-01-31T12:15:43.137Z","dependency_job_id":"9cfcd94b-2984-4f16-9c76-2f48f186bbb4","html_url":"https://github.com/openplayerjs/openplayerjs","commit_stats":{"total_commits":1244,"total_committers":15,"mean_commits":82.93333333333334,"dds":"0.28054662379421225","last_synced_commit":"ad251da3e12f035b66586ffa7d8d83bf78161973"},"previous_names":[],"tags_count":111,"template":false,"template_full_name":null,"purl":"pkg:github/openplayerjs/openplayerjs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openplayerjs%2Fopenplayerjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openplayerjs%2Fopenplayerjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openplayerjs%2Fopenplayerjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openplayerjs%2Fopenplayerjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openplayerjs","download_url":"https://codeload.github.com/openplayerjs/openplayerjs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openplayerjs%2Fopenplayerjs/sbom","scorecard":{"id":709929,"data":{"date":"2025-08-11","repo":{"name":"github.com/openplayerjs/openplayerjs","commit":"b11f5245302be4fdcab024486a75498338eaf86b"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.2,"checks":[{"name":"Code-Review","score":0,"reason":"Found 1/21 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":4,"reason":"2 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 4","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql-analysis.yml:28","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql-analysis.yml:29","Warn: no topLevel permission defined: .github/workflows/codeql-analysis.yml:1","Warn: no topLevel permission defined: .github/workflows/coveralls.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/openplayerjs/openplayerjs/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:45: update your workflow using https://app.stepsecurity.io/secureworkflow/openplayerjs/openplayerjs/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:56: update your workflow using https://app.stepsecurity.io/secureworkflow/openplayerjs/openplayerjs/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:70: update your workflow using https://app.stepsecurity.io/secureworkflow/openplayerjs/openplayerjs/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/coveralls.yml:9: update your workflow using https://app.stepsecurity.io/secureworkflow/openplayerjs/openplayerjs/coveralls.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/coveralls.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/openplayerjs/openplayerjs/coveralls.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/coveralls.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/openplayerjs/openplayerjs/coveralls.yml/master?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/coveralls.yml:18","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   1 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":9,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 14 commits out of 15 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":8,"reason":"2 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T07:49:48.630Z","repository_id":37734870,"created_at":"2025-08-22T07:49:48.630Z","updated_at":"2025-08-22T07:49:48.630Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30137132,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-05T16:58:46.102Z","status":"ssl_error","status_checked_at":"2026-03-05T16:58:45.706Z","response_time":93,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["audio","dash","hls","html5","html5-audio","html5-video","html5-video-player","javascript","openplayerjs","player","typescript","vast","video"],"created_at":"2024-08-03T03:01:12.297Z","updated_at":"2026-03-07T17:11:57.400Z","avatar_url":"https://github.com/openplayerjs.png","language":"TypeScript","readme":"# [OpenPlayer.js](https://www.openplayerjs.com)\n\n![openplayerjs](https://user-images.githubusercontent.com/910829/46182430-d4c0f380-c299-11e8-89a8-c7554a70b66c.png)\n\n[![Coverage Status](https://coveralls.io/repos/github/openplayerjs/openplayerjs/badge.svg)](https://coveralls.io/github/openplayerjs/openplayerjs?branch=master)\n[![JSDelivr](https://data.jsdelivr.com/v1/package/npm/openplayerjs/badge)](https://www.jsdelivr.com/package/npm/openplayerjs)\n\n# OpenPlayerJS — modular, plugin-first, easier to extend\n\nThis is a media player that uses all the goods of HTML5 video/audio elements to play the most popular media in MP4/MP3, HLS and also has the ability to play VMAP / VAST / non linear / companion ads\n\n\u003e **🎉🎉🎉 OpenPlayerJS v3 is finally here!! 🎉🎉🎉**\n\u003e\n\u003e `v3` is a radical internal rebuild that keeps most of the player familiar to use, but makes it **much easier to extend** (controls, plugins, engines) and **much easier to maintain**.\n\u003e\n\u003e ✅ If you use **UMD/CDN** today, you can keep the classic `new OpenPlayerJS('id', options); player.init();` flow with some minor changes — see [**UMD compatibility** section](#-umd-compatibility-the-v2-way-still-works) below.\n\n---\n\n## ✨ What’s new in v3\n\n- 🧩 **Modular packages** (install only what you need)\n- 🔌 **Plugin-first architecture** (UI, Ads, Engines are plugins)\n- 🎛️ **Imperative UI extensions** (`addElement`, `addControl` via `extendControls`)\n- 🧱 Cleaner separation of concerns (core vs UI vs engines/plugins)\n- 🔥 Ads are **no longer using Google IMA SDK**: we have built our own with the support using Dailymotion's open source libraries. This was to support ads all around the world and avoid geoblocking\n\n---\n\n## ❌ Breaking Changes\n\n- ❌ **M(PEG)-DASH / FLV support dropped** in favor of just supporting what browsers natively supports; if there is a need for them in the future, they can be added as separate bundles (like the [hls one](./packages/hls/README.md)).\n- ❌ Core **quality/levels support dropped**: API (`levels`, `level`) — quality is now engine-specific, and will require to be built inside each one of them.\n- ❌ Several v2 \"mega-config\" options (moved to the right package: UI vs engine vs plugin); this approach can work when using UMD files, depending on what plugins are enabled.\n\n\u003e To learn more about these changes, read **[MIGRATION.v3.md](./MIGRATION.v3.md)**\n\n---\n\n## 📦 Packages\n\n| Package              | Purpose                                                                 | Docs                                                     |\n| -------------------- | ----------------------------------------------------------------------- | -------------------------------------------------------- |\n| `@openplayer/core`   | Player lifecycle, plugin system, engines, events                        | [packages/core/README.md](./packages/core/README.md)     |\n| `@openplayer/player` | Default UI + built-in controls + UI extension APIs                      | [packages/player/README.md](./packages/player/README.md) |\n| `@openplayer/hls`    | HLS engine (powered by [`hls.js`](https://github.com/video-dev/hls.js)) | [packages/hls/README.md](./packages/hls/README.md)       |\n| `@openplayer/ads`    | VAST/VMAP/non-linear/companion ads plugin + extension APIs              | [packages/ads/README.md](./packages/ads/README.md)       |\n\n---\n\n## How to use it?\n\n### Verify Cross-Origin Resource Sharing (CORS)\n\nWhen ads, captions, or streaming manifests are loaded from a different domain, the server must allow cross-origin requests. The typical error message looks like:\n\n```\nAccess to fetch at 'https://cdn.example.com/video.m3u8' from origin 'https://myapp.com'\nhas been blocked by CORS policy.\n```\n\nTo fix this on your server, add the following response headers:\n\n```\nAccess-Control-Allow-Origin: https://myapp.com\nAccess-Control-Allow-Credentials: true\n```\n\nOr, for public assets, allow all origins:\n\n```\nAccess-Control-Allow-Origin: *\n```\n\n---\n\n### HTML setup\n\nAll you need in your markup is a standard `\u003cvideo\u003e` or `\u003caudio\u003e` element with a `src` attached to it. Add the `controls` and `playsinline` attributes for cross-browser compatibility, and optionally include `\u003csource\u003e` and `\u003ctrack\u003e` children:\n\n```html\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003clink rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/openplayerjs/dist/openplayer.css\" /\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cvideo id=\"player\" class=\"op-player__media\" controls playsinline\u003e\n      \u003csource src=\"/path/to/video.mp4\" type=\"video/mp4\" /\u003e\n      \u003ctrack kind=\"subtitles\" src=\"/path/to/video.vtt\" srclang=\"en\" label=\"English\" /\u003e\n    \u003c/video\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n\u003e The `op-player__media` class applies the base player styles. The player's wrapper and controls are injected into the DOM automatically when `init()` is called.\n\n#### Bandwidth optimization\n\nTo avoid downloading media before the user presses play, set `preload=\"none\"` on the media element:\n\n```html\n\u003cvideo id=\"player\" class=\"op-player__media\" controls playsinline preload=\"none\"\u003e\n  \u003csource src=\"/video.mp4\" type=\"video/mp4\" /\u003e\n\u003c/video\u003e\n```\n\n\u003e **Side effect:** With `preload=\"none\"` the player cannot read the media's duration until playback starts. Provide the `duration` option if you want the UI to show the correct total time before the user presses play:\n\u003e\n\u003e ```ts\n\u003e new Core(media, { duration: 315 }); // 5 min 15 s or Infinity for live streamings\n\u003e ```\n\n---\n\n### JavaScript / TypeScript (ESM — recommended)\n\nInstall the packages you need:\n\n```bash\n# Core + UI (covers MP4, MP3, OGG, and any other natively-supported format)\nnpm install @openplayer/core @openplayer/player\n\n# Add HLS support (powered by hls.js)\nnpm install @openplayer/hls hls.js\n\n# Add ads support (VAST / VMAP)\nnpm install @openplayer/ads\n```\n\nThen wire everything up:\n\n```ts\nimport { Core } from '@openplayer/core';\nimport { createUI, buildControls } from '@openplayer/player';\nimport '@openplayer/player/style.css';\n\nconst media = document.querySelector\u003cHTMLVideoElement\u003e('#player')!;\n\nconst player = new Core(media, {\n  startTime: 0,\n  startVolume: 1,\n  startPlaybackRate: 1,\n});\n\nconst controls = buildControls({\n  controls: {\n    top: ['progress'],\n    'center-left': ['play', 'duration', 'volume'],\n    'center-right': ['captions', 'fullscreen', 'settings'],\n  },\n});\n\ncreateUI(player, media, controls);\n```\n\n---\n\n### 🌍 UMD compatibility (the “v2 way” still works)\n\nIf you prefer loading scripts from a CDN without a build step:\n\n```html\n\u003clink rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/openplayerjs/dist/openplayer.css\" /\u003e\n\n\u003cvideo id=\"player\" class=\"op-player__media\" controls playsinline\u003e\n  \u003csource src=\"/path/to/video.mp4\" type=\"video/mp4\" /\u003e\n\u003c/video\u003e\n\n\u003c!-- Core + UI --\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/openplayerjs/dist/openplayer.js\"\u003e\u003c/script\u003e\n\u003c!-- Optional: HLS support --\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/openplayerjs/dist/openplayer-hls.js\"\u003e\u003c/script\u003e\n\u003c!-- Optional: Ads support --\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/openplayerjs/dist/openplayer-ads.js\"\u003e\u003c/script\u003e\n\n\u003cscript\u003e\n  const player = new OpenPlayerJS('player', {\n    startTime: 0,\n    startVolume: 1,\n    controls: {\n      top: ['progress'],\n      'center-left': ['play', 'duration', 'volume'],\n      'center-right': ['captions', 'fullscreen', 'settings'],\n    },\n  });\n\n  player.init();\n\u003c/script\u003e\n```\n\n---\n\n## 📚 Legacy docs \u0026 changelog\n\n- Old changelog: **[CHANGELOG.old.md](./CHANGELOG.old.md)**\n- Legacy docs folder (v2 style): **[docs/](https://github.com/openplayerjs/openplayerjs/tree/v2.14.12/docs)**\n\n---\n\n## Built With\n\n- [Typescript](https://www.typescriptlang.org/docs/home.html) - The Javascript for Pros.\n\n## Authors\n\n- **Rafael Miranda** - [rafa8626](https://github.com/rafa8626)\n\nSee also the list of [contributors](https://github.com/openplayerjs/openplayerjs/contributors) who participated in this project.\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md).\n\n## License\n\nThis project is licensed under the MIT License - see [LICENSE.md](LICENSE.md) for details.\n","funding_links":[],"categories":["TypeScript","HarmonyOS","Players"],"sub_categories":["Windows Manager"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenplayerjs%2Fopenplayerjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenplayerjs%2Fopenplayerjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenplayerjs%2Fopenplayerjs/lists"}