Skip to content

Commit

Permalink
Merge pull request #1 from Eyevinn/feat/add-more-playlist-info
Browse files Browse the repository at this point in the history
Feat/add more playlist info
  • Loading branch information
martinstark authored Oct 2, 2024
2 parents 7e386e4 + 0b35e4d commit d7e78f2
Show file tree
Hide file tree
Showing 8 changed files with 3,326 additions and 1,885 deletions.
8 changes: 4 additions & 4 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ extends:

plugins:
- prettier
- '@typescript-eslint'
- "@typescript-eslint"

globals:
Promise: true
Expand All @@ -19,10 +19,10 @@ rules:
- error
arrow-body-style: off
no-console: off
'@typescript-eslint/no-unused-vars': "error"
'@typescript-eslint/explicit-module-boundary-types': off
"@typescript-eslint/no-unused-vars": "error"
"@typescript-eslint/explicit-module-boundary-types": off

parser: '@typescript-eslint/parser'
parser: "@typescript-eslint/parser"

parserOptions:
sourceType: module
5 changes: 5 additions & 0 deletions demo/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ document.addEventListener("DOMContentLoaded", () => {
};
const src =
"https://f53accc45b7aded64ed8085068f31881.egress.mediapackage-vod.eu-north-1.amazonaws.com/out/v1/1c63bf88e2664639a6c293b4d055e6bb/ade303f83e8444d69b7658f988abb054/2a647c0cf9b7409598770b9f11799178/manifest.m3u8";

// demuxed
// const src =
// "https://playertest.longtailvideo.com/adaptive/elephants_dream_v4/index.m3u8";

new SafariBitrateMonitor({
videoElement,
hlsManifestUrl: src,
Expand Down
48 changes: 24 additions & 24 deletions demo/index.html
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Safari Bitrate Monitor</title>
<script type="module" src="demo.js"></script>
</head>

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Safari Bitrate Monitor</title>
<script type="module" src="demo.js"></script>
</head>

<body>
<div id="wrapper">
<video src="https://f53accc45b7aded64ed8085068f31881.egress.mediapackage-vod.eu-north-1.amazonaws.com/out/v1/1c63bf88e2664639a6c293b4d055e6bb/ade303f83e8444d69b7658f988abb054/2a647c0cf9b7409598770b9f11799178/manifest.m3u8" controls>
</video>
</div>
<style>
#wrapper {
width: 100%;
max-width: 800px;
margin: 0 auto;
}

video {
max-width: 100%;
}
</style>
</body>
<body>
<div id="wrapper">
<video
src="https://f53accc45b7aded64ed8085068f31881.egress.mediapackage-vod.eu-north-1.amazonaws.com/out/v1/1c63bf88e2664639a6c293b4d055e6bb/ade303f83e8444d69b7658f988abb054/2a647c0cf9b7409598770b9f11799178/manifest.m3u8"
controls
></video>
</div>
<style>
#wrapper {
width: 100%;
max-width: 800px;
margin: 0 auto;
}

video {
max-width: 100%;
}
</style>
</body>
</html>
81 changes: 77 additions & 4 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,70 @@ export interface IQualityLevel {
bitrate: number;
width: number;
height: number;
fps: number;
audioCodec: string;
videoCodec: string;
}

export interface IHLSPlaylist {
export interface IHLSPlaylist extends IQualityLevel {
url: string;
width: number;
height: number;
bitrate: number;
}

const HLS_ATTRIBUTE_REGEXP = new RegExp(
'(?:,?)([A-Z0-9-]+?)[=](".*?"|[^",]+)(?=,|s*$)',
"g"
);

const guessCodec = (
codecs: string[]
): { audio?: string; video: string } | undefined => {
if (codecs.length === 1) {
return {
audio: undefined,
video: codecs[0],
};
}

if (codecs.length >= 2) {
// Guess based on some of the most common codecs. There is no
// way to be 100% certain which codec belongs to which track
// in the HLS standard.
const firstIsProbablyVideo = codecs[0].includes("avc");
const secondIsProbablyVideo = codecs[1].includes("avc");

const firstIsProbablyAudio = codecs[0].includes("mp4a");
const secondIsProbablyAudio = codecs[1].includes("mp4a");

if (firstIsProbablyVideo) {
return {
video: codecs[0],
audio: codecs[1],
};
}

if (secondIsProbablyVideo) {
return {
video: codecs[1],
audio: codecs[0],
};
}

if (firstIsProbablyAudio) {
return {
video: codecs[1],
audio: codecs[0],
};
}

if (secondIsProbablyAudio) {
return {
video: codecs[0],
audio: codecs[1],
};
}
}
};

const BITRATE_POLL_INTERVAL = 5 * 1000;

export class SafariBitrateMonitor {
Expand Down Expand Up @@ -75,6 +125,9 @@ export class SafariBitrateMonitor {
width: 0,
height: 0,
bitrate: 0,
fps: 0,
audioCodec: "",
videoCodec: "",
};
if (line.includes("#EXT-X-STREAM-INF")) {
let valid = false;
Expand All @@ -93,6 +146,23 @@ export class SafariBitrateMonitor {
playlist.height = Number(height);
break;
}
case "CODECS": {
const codecs = value.replace(/"/g, "").split(",");

const avCodecs = guessCodec(codecs);

playlist.videoCodec = avCodecs.video;
playlist.audioCodec = avCodecs.audio;

break;
}
case "FRAME-RATE":
if (value) {
playlist.fps = Number(value);
}
break;
default:
break;
}
}
if (valid) {
Expand All @@ -118,6 +188,9 @@ export class SafariBitrateMonitor {
bitrate: playlist.bitrate,
width: playlist.width,
height: playlist.height,
videoCodec: playlist.videoCodec,
audioCodec: playlist.audioCodec,
fps: playlist.fps,
});
}
}, this.bitratePollInterval);
Expand Down
Loading

0 comments on commit d7e78f2

Please sign in to comment.