@invintusmedia/tomp4
v1.0.9
Published
Convert MPEG-TS, fMP4, and HLS streams to MP4 with clipping support - pure JavaScript, zero dependencies
Readme
you've got an HLS stream, or some .ts segments, or fMP4 chunks.
you want an .mp4 file.
import toMp4 from '@invintusmedia/tomp4'
const mp4 = await toMp4('https://example.com/stream.m3u8')
mp4.download('my-video.mp4')that's it. no ffmpeg. no wasm. no dependencies.
from different sources
// HLS playlist (auto-picks highest quality)
const mp4 = await toMp4('https://example.com/master.m3u8')
// single .ts segment
const mp4 = await toMp4('https://example.com/segment.ts')
// raw bytes you already have
const mp4 = await toMp4(uint8Array)
// pick your quality
const hls = await toMp4.parseHls('https://example.com/master.m3u8')
console.log(hls.qualities) // ['1080p', '720p', '480p']
const mp4 = await toMp4(hls.select('720p'))clip to time range
// one-step: download HLS + clip (only fetches needed segments)
const mp4 = await toMp4('https://example.com/stream.m3u8', {
startTime: 0,
endTime: 30
})
// clip existing data (snaps to keyframes)
const mp4 = await toMp4(data, {
startTime: 5,
endTime: 15
})analyze without converting
const info = toMp4.analyze(tsData)
info.duration // 99.5 (seconds)
info.keyframes // [{index: 0, time: 0}, {index: 150, time: 5.0}, ...]
info.videoCodec // "H.264/AVC"
info.audioCodec // "AAC"progress callback
const mp4 = await toMp4(url, {
onProgress: (msg, info) => {
if (info?.percent !== undefined) {
console.log(`${info.percent}% - ${msg}`)
}
}
})
// 10% - Downloading: 10%
// 50% - Downloaded 5.2 MB
// 60% - Frames: 300 video, 450 audio
// 100% - Completeuse the result
mp4.download('video.mp4') // trigger download
video.src = mp4.toURL() // play in video element
mp4.data // Uint8Array
mp4.toBlob() // Blob
mp4.toArrayBuffer() // ArrayBuffer
mp4.revokeURL() // free memory
what it does
remuxes video. no transcoding.
| input | output |
|-------|--------|
| .ts (MPEG-TS) | .mp4 |
| .m4s (fMP4) | .mp4 |
| .m3u8 (HLS) | .mp4 |
video: H.264, H.265
audio: AAC
what it doesn't do
- transcode (no converting h264→h265, etc)
- handle DRM/encrypted streams
- support MP3, AC-3 audio (yet)
browser + node
works in both. ~50kb minified.
<script type="module">
import toMp4 from '@invintusmedia/tomp4'
</script>
MIT
