Skip to main content

Get Started

Install

NPM

npm i frameflow

HTML script

<script src='https://unpkg.com/frameflow/dist/frameflow.min.js' ></script>

Create source

Accept multiple type of sources, e.g. url / path / Blob / ArrayBuffer / ReadableStream. TypeScript will give hints.

let video = await fflow.source('./test.avi')

Get metadata

Metadata can provide you some information, which can be used for filters' arguments. And internally, they are also used for checking your created filter graph, which will explain in filters.

let video = await fflow.source('./test.avi')
console.log(video.duration) // get one item in metadata
console.log(video.metadata) // get all metadata information (container + tracks)

Tracks selection

Usually, we can directly operate on multiple tracks as a group. And one track is seen as a group in which only one element. Thus, created source is also a group. And it is also convenient to apply filters to a group of tracks at a time.

let video = await fflow.source('./test.avi') // return a TrackGroup
let audioTrackGroup = video.filter('audio') // return a new TrackGroup (contain only audio tracks)
let audioTracks = audioTrackGroup.tracks() // return an array of Tracks. (audio)
let newGroup = fflow.group([audioTracks[0], audioTracks[1]]) // group multiple tracks into one group

Transcode

One of core use cases is to convert audio/video files into another with different parameters, e.g. format, codec. Here you just need to focus on source and target, using Export function. It will build a graph internally to execute. There are three ways to export, meeting your various use cases.

exportTo: fastest way

This api can export to multiple types of outputs, e.g. url / path / Blob / ArrayBuffer.

let video = await fflow.source('./test.avi')
await video.exportTo('./out_test.mp4') // no return
let blob = await video.exportTo(Blob) // return a new blob

export + for...of: flexible way with automatic pace

let target = await video.export()
for await (let chunk of target) {
/* post-processing chunk */
chunk.data // Uint8Array (browser) / Buffer (node)
chunk.offset // chunk offset position (bytes) in the output file
}

export + next: most flexible way with manual control

Actually this way is the basic method for above two ways.

let target = await video.export()
let chunk = await target.next()
while (chunk.data) {
/* post-processing chunk */
chunk = await target.next()
}
// execute this line if quitting halfway.
await target.close()