Created
February 3, 2024 12:33
-
-
Save Danielduel/289ddf73a3c6a53dd434048e1bacd7ee to your computer and use it in GitHub Desktop.
Tool for creating a m3u8 playlist file out of a folder of fragmented AV files (.ts).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Example usages | |
* | |
* deno run -A LINK_TO_RAW_OF_THIS_GIST | |
* | |
* deno run -A LINK_TO_RAW_OF_THIS_GIST \ | |
* --path "/path/to/your/folder/with/data" | |
* | |
* deno run -A LINK_TO_RAW_OF_THIS_GIST \ | |
* --path "/path/to/your/folder/with/data" \ | |
* --name "customname.m3u8" | |
* | |
* deno run -A LINK_TO_RAW_OF_THIS_GIST \ | |
* --name "customname.m3u8" | |
* | |
* | |
* | |
* Manual | |
* | |
* Tool for creating a m3u8 playlist file out of a folder of fragmented AV files (.ts). | |
* The main use-case of this script is to link together fragments after you've got | |
* a recording in obs and it is known to create wrong playlist file (.m3u8). | |
* This script assumes: | |
* Your fragment files have `.ts` extension. | |
* Your fragment files have ordering suffix after a dash. | |
* Your fragment files are in a single directory. | |
* In short, those are first 3, then 100th, 101th and n segment file: | |
* `something-0.ts`, | |
* `something-1.ts`, | |
* `something-2.ts`, | |
* ... | |
* `something-99.ts`, | |
* `something-100.ts`, | |
* ... | |
* `something-n.ts` | |
* | |
* In my case, I am recording my daily streams and my obs configuration is as follows: | |
* Settings/Output/Recording: | |
* Recording path: `/home/user/Videos/streams/` | |
* Recording format: `HLS(.m3u8 + .ts)` | |
* Settings/Advanced/Recording: | |
* Filename Formatting: `%CCYY-%MM-%DD/%CCYY-%MM-%DD %hh-%mm-%ss` | |
* | |
* Optional arguments: | |
* --path <path> Path to a single directory, without leading slash, can be absolute, | |
* defaults to `.` | |
* --name <name> Name of generated playlist file, it is saved in the same directory as | |
* your path argument points to, defaults to `playlist.m3u8` | |
* | |
*/ | |
import { parseArgs } from "https://deno.land/[email protected]/cli/parse_args.ts"; | |
const args = parseArgs(Deno.args, { | |
string: ["path", "name"] | |
}); | |
const path = args.path || "."; | |
const name = args.name || "playlist.m3u8"; | |
const fileIterator = Deno.readDirSync(path) | |
const fileArrayUnsorted = [...fileIterator]; | |
type SegmentFileEntry = Deno.DirEntry & { | |
segmentName: string; | |
last: number; | |
} | |
const segmentArray = fileArrayUnsorted | |
.filter(({ name }) => { | |
return name.includes(".ts"); | |
}) | |
.map((data): SegmentFileEntry => { | |
const [segmentName] = data.name.split(".ts"); | |
const last = segmentName.split("-").pop()!; | |
return { | |
...data, | |
segmentName, | |
last: +last | |
}; | |
}) | |
.sort((a, b) => { | |
return a.last - b.last; | |
}); | |
const duration = 2; | |
const header = ` | |
#EXTM3U | |
#EXT-X-VERSION:3 | |
#EXT-X-TARGETDURATION:${duration} | |
#EXT-X-MEDIA-SEQUENCE:2426 | |
`; | |
const suffix = ` | |
#EXT-X-ENDLIST | |
`; | |
const item = (name: string) => ` | |
#EXTINF:2.000000, | |
${name} | |
`; | |
const result = ` | |
${header} | |
${segmentArray.map(({name}) => item(name)).join("")} | |
${suffix} | |
` | |
.split("\n") | |
.filter(line => line !== "") | |
.join("\n") | |
Deno.writeTextFileSync(`${path}/${name}`, result); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment