Skip to content

Commit

Permalink
Ship an HLS.js fork until v1.6.0 is out (@mixwave/hls.js on npm) (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
matvp91 authored Oct 10, 2024
1 parent d6341a1 commit 65f63b0
Show file tree
Hide file tree
Showing 43 changed files with 826 additions and 644 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
<a href="https://matvp91.github.io/mixwave/getting-started.html">Getting Started</a>
</p>

[<img src="./public/button-buy-me-a-coffee.png" width="150" alt="Buy me a coffee button"/>](https://www.buymeacoffee.com/matvp91)
[<img src="./public/button-buy-me-a-coffee.png" width="150" alt="Buy me a coffee button"/>](https://www.buymeacoffee.com/matvp91)

</div>

Mixwave is a self hostable platform that aims to simplify the complexities of video delivery. Transcode and package your media for online streaming with simple API calls and sane defaults, or craft dynamic HLS playlists on the fly with bumpers, ads and filters.
Expand Down Expand Up @@ -57,14 +58,15 @@ There's more info in the [Getting Started](https://matvp91.github.io/mixwave/get

## Player

We built a `facade` that simplifies working with [HLS.js](https://github.com/video-dev/hls.js) and React player components.
We built a `facade` that simplifies working with [HLS.js](https://github.com/video-dev/hls.js) and React player components.

* **Demo**: We created a sample on [StackBlitz - Mixwave Player Demo](https://stackblitz.com/edit/mixwave-player-demo) if you're interested in the implementation details.
* **Documentation**: There's a separate [README](https://github.com/matvp91/mixwave/tree/main/packages/player) dedicated to the player module.
- **Demo**: We created a sample on [StackBlitz - Mixwave Player Demo](https://stackblitz.com/edit/mixwave-player-demo) if you're interested in the implementation details.
- **Documentation**: There's a separate [README](https://github.com/matvp91/mixwave/tree/main/packages/player) dedicated to the player module.

```sh
# make sure hls.js is atleast v1.6.0, with interstitials support.
npm i hls.js
# When hls.js releases v1.6.0, we'll deprecate our own fork. For now, we'll use it
# as it contains interstitials support.
npm i @mixwave/hls.js
npm i @mixwave/player
```

Expand Down
9 changes: 6 additions & 3 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { defineConfig } from "vitepress";
export default defineConfig({
base: "/mixwave/",
title: "Mixwave",
description: "A friendly API to simplify the complexities of video delivery.",
description:
"All-in-one toolkit handles everything from video source to player.",
lang: "en-US",
head: [
[
"script",
Expand Down Expand Up @@ -56,8 +58,9 @@ export default defineConfig({
{
text: "Miscellaneous",
items: [
{ text: "Tips", link: "tips" },
{ text: "Toolset", link: "toolset" },
{ text: "Contribute", link: "misc/contribute" },
{ text: "Tips", link: "misc/tips" },
{ text: "Credits", link: "misc/credits" },
],
},
],
Expand Down
18 changes: 10 additions & 8 deletions docs/features/package.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ next:
Video packaging refers to the process of preparing a video file for delivery and consumption by users across different devices and platforms.

- The video is split into smaller segments or chunks, usually a few seconds long, to facilitate adaptive bitrate streaming (ABR), which adjusts quality based on network conditions.

- A manifest file (m3u8 for HLS) is generated. It contains metadata about the available segments, bitrates, and resolutions, helping the player know what content to request based on the user’s network conditions.

## API
Expand Down Expand Up @@ -44,16 +43,19 @@ Your asset is now available for playback at:
Each package result is uploaded to /package/{assetId}/hls/master.m3u8
:::

## Example
### Alternative name

We started by [transcoding](/features/transcode#example) two input files (content.mp4 and bumper.mp4) to multiple streams. We'll now package these their HLS master and media playlists files.
By default, the package job pushes the result to a folder named `hls`. You can use the `name` param to change the output folder. Think of it this way, we'd like to package a plain HLS playlist by default, but we want for the same transcode result a DRM (encrypted) playlist, which we then call `hls_drm`.

```json
{
"assetId": "f7e89553-0d3b-4982-ba7b-3ce5499ac689",
"name": "hls_drm"
}
```
input = 67b070fd-5db6-4022-a568-652abdbfac9c
output = https://my.cdn/package/67b070fd-5db6-4022-a568-652abdbfac9c/hls/master.m3u8
```

Your asset is now available for playback at:

```
input = 13b1d432-ec8e-4516-9904-df1aa90db803
output = https://my.cdn/package/13b1d432-ec8e-4516-9904-df1aa90db803/hls/master.m3u8
{S3_PUBLIC_URL}/package/f7e89553-0d3b-4982-ba7b-3ce5499ac689/hls_drm/master.m3u8
```
43 changes: 18 additions & 25 deletions docs/features/stitcher.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ Stitcher is a playlist manipulator that can insert HLS interstitials on-the-fly.
- Add a bumper manifest at the start of a playlist, like Netflix' intro.
- Filter media playlists to fit your needs.

Providing input for the stitcher happens in the form of a `uri`. The support uri schemas are:

- `asset://{uuid}` - Aslong as you stay within the Mixwave ecosystem, each asset can be referenced with this schema. Stitcher will know what to do.
- `http(s)://example.com/video/master.m3u8` - Provide a master playlist from elsewhere.

## Create a session

Each playout to a viewer can be considered a session.
Expand All @@ -26,11 +31,15 @@ A minimal body payload may look like this:

```json
{
"assetId": "f7e89553-0d3b-4982-ba7b-3ce5499ac689"
"uri": "asset://f7e89553-0d3b-4982-ba7b-3ce5499ac689",
// or
"uri": "https://example.com/video/master.m3u8"
}
```

Behind the scenes, stitcher will create a session and return you a personalised playlist url. Each session is identifiable by a randomly generated uuid. In the example below, we got back a new session with id `44220f14-ffdd-4cfa-a67f-62ef421b4460`. As all we did was create a session with an `assetId`, the resulting master playlist will only cover that asset. Scroll further down if you'd like to extend the session with ads or a bumper.
Behind the scenes, stitcher will create a session and return you a personalised playlist url. Each session is identifiable by a randomly generated uuid. In the example below, we got back a new session with id `44220f14-ffdd-4cfa-a67f-62ef421b4460`. As all we did was create a session with an `uri`, the resulting master playlist will only cover that asset. Scroll further down if you'd like to extend the session with ads or a bumper.

Stitcher responds with the following:

```json
{
Expand All @@ -50,7 +59,7 @@ When streaming over networks with limited bandwidth (e.g., mobile networks), rem

```json
{
"assetId": "f7e89553-0d3b-4982-ba7b-3ce5499ac689",
"uri": "asset://f7e89553-0d3b-4982-ba7b-3ce5499ac689",
"filter": {
"resolution": "> 480"
}
Expand All @@ -63,25 +72,25 @@ Let's say you transcoded and packaged a new asset with the id `abbda878-8e08-40f

```json
{
"assetId": "f7e89553-0d3b-4982-ba7b-3ce5499ac689",
"uri": "asset://f7e89553-0d3b-4982-ba7b-3ce5499ac689",
"interstitials": [
{
"timeOffset": 10,
"assetId": "abbda878-8e08-40f6-ac8b-3507f263450a"
"uri": "asset://abbda878-8e08-40f6-ac8b-3507f263450a"
}
]
}
```

<video class="video-frame" src="/dashboard-player-bumper.mp4#t=19" controls></video>
<video class="video-frame" src="/video/InterstitialBumper.mp4" controls></video>

### VMAP

Instruct stitcher to add interstitials based on VMAP definitions. Each VMAP contains one or more `AdBreak` elements with a position of where the interstitial should be.
Instruct stitcher to add interstitials based on [VMAP](https://www.iab.com/guidelines/vmap/) definitions. Each VMAP contains one or more `AdBreak` elements with a position of where the interstitial should be.

```json
{
"assetId": "f7e89553-0d3b-4982-ba7b-3ce5499ac689",
"uri": "asset://f7e89553-0d3b-4982-ba7b-3ce5499ac689",
"vmap": {
"url": "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpremidpost&ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&cmsid=496&vid=short_onecue&correlator="
}
Expand All @@ -97,20 +106,4 @@ Instruct stitcher to add interstitials based on VMAP definitions. Each VMAP cont
Ad impressions are not tracked yet, we'd eventually like to provide a client wrapper that tracks ads in a certified manner.
:::

<video class="video-frame" src="/dashboard-player-vmap.mp4#t=4" controls></video>

## Example

In the [package](/features/package#example) and [transcode](/features/transcode#example) example we created 2 HLS master playlists, we can create a new master playlist on the fly which mimics the content asset id (originally from content.mp4), and add a bumper interstitial at time 0.

```
input = - assetId: 67b070fd-5db6-4022-a568-652abdbfac9c
- interstitials: [
{
timeOffset: 0,
assetId: 13b1d432-ec8e-4516-9904-df1aa90db803
}
]
output = http://my.stitcher/session/7b2a354a-69e3-4c16-accb-aa521c8b9d5b/master.m3u8
```
<video class="video-frame" src="/video/AdInsertion.mp4" controls></video>
27 changes: 2 additions & 25 deletions docs/features/transcode.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ Video transcoding is the process of converting video from one format to another.

This dynamic delivery ensures smooth playback across various network conditions and devices, making the video experience better for everyone.

<video class="video-frame" src="/video/TranscodeAndPackage.mp4" controls></video>

## Dashboard

You can use the dashboard to either view pending, processing, finished or failed transcode jobs, or you can use it to interact with the API. In the video below, we'll demonstrate how to transcode an mp4 file to a variety of streams.

<video class="video-frame" src="/dashboard-transcode.mp4" controls></video>

## API

The transcode endpoint will push a job to the queue. The trancode job will create a separate ffmpeg job for each output stream defined in the body.
Expand Down Expand Up @@ -110,26 +110,3 @@ Know that the result of a transcode job is merely an intermediary format. Typica
:::

Mixwave' transcode API works slightly different than what others do. We emphasize the idea to define what you have (input) and what you need (streams), and the system shall figure out how to craft the streams. There's no need to directly link an input with a given output.

## Example

In the example below, we'll transcode 2 mp4 files (content.mp4 and bumper.mp4) to 2 video tracks and an English audio track. The result are 2 asset id's, one for each.

```
input = content.mp4
streams = - video 1080p
- video 720p
- audio eng
output = 67b070fd-5db6-4022-a568-652abdbfac9c
```

```
input = bumper.mp4
streams = - video 720p
- audio eng
output = 13b1d432-ec8e-4516-9904-df1aa90db803
```
6 changes: 1 addition & 5 deletions docs/frontend/dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,4 @@ The dashboard is a client application that visualizes running jobs, its statuses

Typically, you'd want to build the dashboard once and upload it to `S3` to serve it as a static site. The dashboard is an SPA and requires no separate server / backend to function.

<video class="video-frame" src="/dashboard-jobs.mp4" controls></video>

You can use the API docs to interact with the API, as seen here:

<video class="video-frame" src="/dashboard-transcode.mp4" controls></video>
Verify you've set the correct variables in `config.env`, each env key prefixed with `PUBLIC_` will be available in the dashboard and will be included in the final JS bundle.
Loading

0 comments on commit 65f63b0

Please sign in to comment.