gpac(1)
💖 gpac — the manual, bestie edition 💖
okay so. this is gpac(1), the GPAC command-line filter session manager. yes it's long. yes it's iconic. grab a snack 🍓
✨ NAME ✨
gpac — GPAC command-line filter session manager 👑
🌈 SYNOPSIS 🌈
---
# 🦋 DESCRIPTION 🦋
This page describes <hotpink>all filters usually present in GPAC</hotpink>. fr fr, that's the whole vibe.
Wanna check help on a filter that is *not* listed here? No stress, just do:
💅 inspect
Description: Packet inspector 👀
The inspect filter can be used to dump PID and packets. It may also be used to check parts of payload of the packets.
The default options inspect only PID changes. If full is not set, mode is forced to frame and PID properties are formatted in human-readable form, one PID per line. Otherwise, all properties are dumped.
Note: specifyingxml,analyze,fmtor using-for-testwill forcefullto true. no cap.
🎀 Custom property dumping
The packet inspector can be configured to dump specific properties of packets using fmt.
When the option is not present, all properties are dumped. Otherwise, only properties identified by $TOKEN$ are printed. You may use '$', '@' or '%' for TOKEN separator. TOKEN can be:
pn: packet (frame in framed mode) numberdts: decoding time stamp in stream timescale,N/Aif not availableddts: difference between current and previous packets decoding time stamp in stream timescale,N/Aif not availablects: composition time stamp in stream timescale,N/Aif not availabledcts: difference between current and previous packets composition time stamp in stream timescale,N/Aif not availablectso: difference between composition time stamp and decoding time stamp in stream timescale,N/Aif not availabletmcd: timecode as provided in SEI,N/Aif not available (requires reframer)dur: duration in stream timescaleframe: framing statusinterface: complete AU, interface object (no size info). Typically a GL textureframe_full: complete AUframe_start: beginning of frameframe_end: end of frameframe_cont: frame continuation (not beginning, not end)
saporrap: SAP type of the frameilace: interlacing flag (0: progressive, 1: top field, 2: bottom field)corr: corrupted packet flagseek: seek flagbo: byte offset in source,N/Aif not availableroll: roll infocrypt: crypt flagvers: carousel version numbersize: size of packetcsize: total size of packets received so farcrc: 32 bit CRC of packetlforn: insert new linet: insert tabdata: hex dump of packet (big output!) or as string if legal UTF-8lp: leading picture flagdepo: depends on other packet flagdepf: is depended on other packet flagred: redundant coding flagstart: packet composition time asHH:MM:SS.msstartc: packet composition time asHH:MM:SS,msend: packet end time asHH:MM:SS.msendc: packet end time asHH:MM:SS,msck: clock type used for PCR discontinuitiespcr: MPEG-2 TS last PCR,n/aif not availablepcrd: difference between last PCR and decoding time,n/aif no PCR availablepcrc: difference between last PCR and composition time,n/aif no PCR availableP4CC: 4CC of packet propertyPropName: Name of packet propertypid.P4CC: 4CC of PID propertypid.PropName: Name of PID propertyfn: Filter name
🧚 Example
fmt="PID $pid.ID$ packet $pn$ DTS $dts$ CTS $cts$ $lf$"
This dumps packet number, cts and dts as follows: PID 1 packet 10 DTS 100 CTS 108
An unrecognized keyword or missing property will resolve to an empty string. periodt.
Note: when dumping in interleaved mode, there is no guarantee that the packets will be dumped in their original sequence order since the inspector fetches one packet at a time on each PID. 😭
🫶 Note on playback
Buffering can be enabled to check the input filter chain behaviour, e.g. check HAS adaptation logic.
The various buffering options control when packets are consumed. Buffering events are logged using media@info for state changes and media@debug for media filling events.
The speed option is only used to configure the filter chain but is ignored by the filter when consuming packets.
If real-time consumption is required, a reframer filter must be setup before the inspect filter.
Example
gpac -i SRC reframer:rt=on inspect:buffer=10000:rbuffer=1000:mbuffer=30000:speed=2
This will play the session at 2x speed, using 30s of maximum buffering, consuming packets after 10s of media are ready and rebuffering if less than 1s of media. slay 💅
🌸 Options (expert)
log(str, default:stdout, Enum:_any|stderr|stdout|GLOG|TL|null) — set probe log filename_any: target file path and namestderr: dump to stderrstdout: dump to stdoutGLOG: use GPAC logsapp@infoTL: use GPAC log toolTLat levelinfonull: silent mode
mode(enum, default:pck) — dump modepck: dump full packetblk: dump packets before reconstructionframe: force reframerraw: dump source packets without demultiplexing
interleave(bool, default:true) — dump packets as they are received on each PID. Iffalse, logs are reported for each PID at end of sessiondeep(bool, default:false, updatable) — dump packets along with PID state change, implied whenfmtis setprops(bool, default:true, updatable) — dump packet properties, ignored whenfmtis setdump_data(bool, default:false, updatable) — enable full data dump (very large output), ignored whenfmtis setfmt(str, updatable) — set packet dump formathdr(bool, default:true) — print a header corresponding tofmtstring without'$'or"pid"allp(bool, default:false) — analyse for the entire duration, rather than stopping when all PIDs are foundinfo(bool, default:false, updatable) — monitor PID info changesfull(bool, default:false, updatable) — full dump of PID properties (always on if XML)pcr(bool, default:false, updatable) — dump M2TS PCR infospeed(dbl, default:1.0) — set playback command speed. If negative andstartis0,startis set to-1start(dbl, default:0.0) — set playback start offset. A negative value means percent of media duration with-1equal to durationdur(frac, default:0/0) — set inspect durationanalyze(enum, default:off, updatable) — analyze sample content (NALU, OBU), similar to-bsdbgoption of reframer filtersoff: no analyzingon: simple analyzingbs: log bitstream syntax (all elements read from bitstream)full: log bitstream syntax and bit sizes signaled as(N)after field value, except 1-bit fields (omitted)
xml(bool, default:false, updatable) — use xml formatting (implied if(-analyze]()is set) and disablefmtcrc(bool, default:false, updatable) — dump crc of samples of subsamples (NALU or OBU) when analyzingfftmcd(bool, default:false, updatable) — consider timecodes use ffmpeg-compatible signaling rather than QT compliant onedtype(bool, default:false, updatable) — dump property typebuffer(uint, default:0) — set playback buffer in msmbuffer(uint, default:0) — set max buffer occupancy in ms. If less thanbuffer, usebufferrbuffer(uint, default:0, updatable) — rebuffer trigger in ms. If0or more thanbuffer, disable rebufferingstats(bool, default:false) — compute statistics for PIDstimeout(uint, default:5000) — timeout in ms when doing simple inspection in case no packets are received on some PIDstest(enum, default:no, updatable) — skip predefined set of properties, used for test modeno: no properties skippednoprop: all properties/info changes on PID are skipped, only packets are dumpednetwork: URL/path dump, cache state, file size properties skipped (used for hashing network results)netx: same asnetworkbut skip track duration and templates (used for hashing progressive load of fmp4)encode: same asnetworkplus skip decoder config (used for hashing encoding results)encx: same asencodeand skip bitrates, media data size and conocrc: disable packet CRC dumpnobr: skip bitrate
🔥 probe
Description: Source prober 🔍
The Probe filter is used by applications (typically MP4Box) to query demultiplexed PIDs (audio, video, ...) available in a source chain.
The filter outputs the number of input PIDs in the file specified by log. It is up to the app developer to query input PIDs of the prober and take appropriated decisions. iykyk 🫶
🌸 Options (expert)
log(str, default:stdout, Enum:_any|stderr|stdout|GLOG|null) — set probe log filename to print number of streams_any: target file path and namestderr: dump to stderrstdout: dump to stdoutGLOG: use GPAC logsapp@infonull: silent mode
👑 compositor
Description: Compositor 🎬
The GPAC compositor allows mixing audio, video, text and graphics in a timed fashion.
The compositor operates either in media-client or filter-only mode.
🦋 Media-client mode
In this mode, the compositor acts as a pseudo-sink for the video side and creates its own output window.
The video frames are dispatched to the output video PID in the form of frame pointers requiring later GPU read if used.
The audio part acts as a regular filter, potentially mixing and resampling the audio inputs to generate its output.
User events are directly processed by the filter in this mode. main character energy fr 💅
🎀 Filter mode 🎀
okay so in this mode the compositor is literally just a regular filter, generating frames based on the scene you loaded. no cap. 💖
It builds its outputs from the input video frames, and it will process user events sent by the consuming filter(s). ✨
If there are no input video frames (think pure BIFS / SVG / VRML), the filter generates frames based on the fps, at constant or variable frame rate — whichever you set up.
It stops generating frames the second all input streams are done, unless that gets extended/reduced by dur. 🛑
If audio streams are loaded, an audio output PID gets created. 🎵
The default output pixel format in filter mode is:
rgbwhen the filter is explicitly loaded by the applicationrgbawhen the filter is loaded during a link resolution
You can change that by assigning the opfmt option. Also, heads up bestie: if either opfmt specifies an alpha channel or bc is not 0 but has alpha=0, background creation in the default scene will be skipped. 💅
In filter-only mode, the special URL gpid:// is used to locate PIDs in the scene description, so you can design scenes independently from source media. 🦋 When such a PID is associated to a Background2D node in BIFS (no SVG mapping yet), the compositor operates in pass-through mode. In this mode, only new input frames on the pass-through PID generate new frames, and the scene clock matches the input packet time. The output size and pixel format get set to the input size and pixel format, unless you specified otherwise in the filter options.
If only 2D graphics are used and the display driver is not forced, 2D rasterizing happens in the output pixel format (including YUV pixel formats). In that case, in-place processing (rasterizing over the input frame data) is used whenever the input data allows it. 🔥
If 3D graphics are used, or the display driver is forced, OpenGL gets used on an offscreen surface and the output packet will be an OpenGL texture. 👑
🌈 Specific URL syntaxes 🌈
The compositor accepts any URL type supported by GPAC. It also accepts these schemes for URLs:
views://— creates an auto-stereo scene of N views fromviews://v1::...::vNmosaic://— creates a mosaic of N views frommosaic://v1::...::vN
For both syntaxes, vN can be any type of URL supported by GPAC.
For the views:// syntax, the number of rendered views is set by nbviews:
- If the URL gives less views than rendered, the views will be repeated
- If the URL gives more views than rendered, the extra views will be ignored
The compositor can act as a source filter when the src option is explicitly set, independently from the operating mode:
gpac compositor:src=source.mp4 vout
And the compositor can also act as a source filter when the source url uses one of the compositor's built-in protocol schemes:
gpac -i mosaic://URL1:URL2 vout
✨ Options (expert): ✨
okay these are the deep cuts, the lore, the expert settings. strap in bestie, there's a lot. 🫶
aa(enum, default:all, updatable) — set the anti-aliasing mode for raster graphics. Whether the setting actually gets applied or not depends on the graphics module or graphic card, iykyk.none— no anti-aliasingtext— anti-aliasing for text onlyall— complete anti-aliasing
hlfill(uint, default:0x0, updatable) — set the highlight fill color (ARGB)hlline(uint, default:0xFF000000, updatable) — set the highlight stroke color (ARGB)hllinew(flt, default:1.0, updatable) — set the highlight stroke widthsz(bool, default:true, updatable) — enable scalable zoom. When scalable zoom is enabled, resizing the output window will also recompute all vectorial objects. Otherwise only the final buffer is stretched.bc(uint, default:0, updatable) — default background color to use when displaying transparent images or video with no scene composition instructionsyuvhw(bool, default:true, updatable) — enable YUV hardware for 2D blitblitp(bool, default:true, updatable) — partial hardware blit. If it's not set, it will force more redraw.softblt(bool, default:true) — enable software blit/stretch in 2D. If disabled, the vector graphics rasterizer will always be used.stress(bool, default:false, updatable) — enable stress mode of the compositor (rebuilds all vector graphics and texture states at each frame) 😭fast(bool, default:false, updatable) — enable speed optimization. Whether the setting is applied or not depends on the graphics module / graphic card.bvol(enum, default:no, updatable) — draw the bounding volume of objectsno— disable bounding boxbox— draws a rectangle (2D) or box (3D)aabb— draws axis-aligned bounding-box tree (3D) or rectangle (2D)
textxt(enum, default:default, updatable) — specify whether text shall be drawn to a texture and then rendered, or directly rendered. Using textured text can improve text rendering in 3D and also improve text-on-video like content. 💜default— use texturing for OpenGL rendering, no texture for 2D rasterizernever— never uses text texturesalways— always render text to texture before drawing
out8b(bool, default:false, updatable) — convert 10-bit video to 8 bit texture before GPU uploaddrop(bool, default:false, updatable) — drop late frame when drawing. If not set, frames are not dropped until a desynchronization of 1 second or more is observed.sclock(bool, default:false, updatable) — force synchronizing all streams on a single clocksgaze(bool, default:false, updatable) — simulate gaze events through mouseckey(uint, default:0, updatable) — color key to use in windowless mode (0xFFRRGGBB). GPAC currently does not support true alpha blitting to desktop due to limitations in most windowing toolkit, so it uses a color keying mechanism instead. The alpha part of the key is used for global transparency of the output, if supported.timeout(uint, default:10000, updatable) — timeout in ms after which a source is considered dead (0disables the timeout)fps(frac, default:30/1, updatable) — simulation frame rate when animation-only sources are played (ignored when video is present)timescale(uint, default:0, updatable) — timescale used for output packets when there's no input video PID. A value of0means fps numerator.autofps(bool, default:true) — use video input fps for output, ignored in player mode. If there's no video or it's not set, it usesfps.vfr(bool, default:false) — only emit frames when changes are detected. (always true in player mode and when the filter is dynamically loaded)dur(dbl, default:0, updatable) — duration of generation. Mostly used when no video input is present. Negative values mean number of frames, positive values mean duration in seconds,0stops as soon as all streams are done.fsize(bool, default:false, updatable) — force the scene to resize to the biggest bitmap available if no size info is given in the BIFS configurationmode2d(enum, default:defer, updatable) — specify whether immediate drawing should be used or notimmediate— the screen is completely redrawn at each frame (always on if pass-through mode is detected)defer— object positioning is tracked from frame to frame and dirty rectangles info is collected in order to redraw the minimal amount of the screen bufferdebug— only renders changed areas, resetting other areas- Whether the setting is applied or not depends on the graphics module and player mode.
amc(bool, default:true) — audio multichannel support; if disabled, always down-mix to stereo. Useful if the multichannel output does not work properly. 🎧asr(uint, default:0) — force output sample rate (0for auto)ach(uint, default:0) — force output channels (0for auto)alayout(uint, default:0) — force output channel layout (0for auto)afmt(afmt, default:s16, Enum:none|u8|s16|s16b|s24|s24b|s32|s32b|flt|fltb|dbl|dblb|u8p|s16p|s24p|s32p|fltp|dblp) — force output channel format (0for auto)asize(uint, default:1024) — audio output packet size in samplesabuf(uint, default:100) — audio output buffer duration in ms — the audio renderer fills the output PID up to this value. A too low value will lower latency but can have real-time playback issues. ⚠️avol(uint, default:100, updatable) — audio volume in percentapan(uint, default:50, updatable) — audio pan in percent,50is no panasync(bool, default:true, updatable) — audio resynchronization; if disabled, audio data is never dropped but may get out of syncmax_aspeed(dbl, default:2.0, updatable) — silence audio if playback speed is greater than the specified valuemax_vspeed(dbl, default:4.0, updatable) — move to i-frame only decoding if playback speed is greater than the specified valuebuffer(uint, default:3000, updatable) — playout buffer in ms (overridden byBufferLengthproperty of input PID)rbuffer(uint, default:1000, updatable) — rebuffer trigger in ms (overridden byRebufferLengthproperty of input PID)mbuffer(uint, default:3000, updatable) — max buffer in ms, must be greater than playout buffer (overridden byBufferMaxOccupancyproperty of input PID)ntpsync(uint, default:0, updatable) — ntp resync threshold in ms (drops frames if their NTP is more than the given threshold above local ntp),0disables ntp dropnojs(bool, default:false) — disable javascriptnoback(bool, default:false) — ignore background nodes and viewport fill (useful when dumping to PNG) 🖼️ogl(enum, default:auto, updatable) — specify 2D rendering modeauto— automatically decides between on, off and hybrid based on contentoff— disables OpenGL; 3D will not be renderedon— uses OpenGL for all graphics; this will involve polygon tesselation and 2D graphics will not look as nice as 2D modehybrid— the compositor performs software drawing of 2D graphics with no textures (better quality) and uses OpenGL for all 2D objects with textures and 3D objects
pbo(bool, default:false, updatable) — enable PixelBufferObjects to push YUV textures to GPU in OpenGL Mode. This may slightly increase the performance of the playback. ⚡nav(enum, default:none, updatable) — override the default navigation mode of MPEG-4/VRML (Walk) and X3D (Examine)none— disables navigationwalk— 3D world walkfly— 3D world fly (no ground detection)pan— 2D/3D world zoom/pangame— 3D world game (mouse gives walk direction)slide— 2D/3D world slideexam— 2D/3D object examineorbit— 3D object orbitvr— 3D world VR (yaw/pitch/roll)
linegl(bool, default:false, updatable) — indicate that outlining shall be done through OpenGL pen width rather than vectorial outliningepow2(bool, default:true, updatable) — emulate power-of-2 textures for OpenGL (old hardware). Ignored if the OpenGL rectangular texture extension is enabled.true— video texture is not resized but emulated with padding. This usually speeds up video mapping on shapes but disables texture transformationsfalse— video is resized to a power of 2 texture when mapping to a shape
paa(bool, default:false, updatable) — do we want polygon antialiasing when we're in full antialiasing mode? If you don't set it, only lines and points get antialiased, bestie 💅bcull(enum, default:on, updatable) — whether backface culling is disabled or noton: backface culling is ON, slayoff: backface culling is OFFalpha: backface culling only kicks in for transparent meshes
wire(enum, default:none, updatable) — wireframe mode, okurrnone: objects drawn as solidonly: objects drawn as wireframe onlysolid: objects drawn solid, and then the wireframe gets drawn on top
norms(enum, default:none, updatable) — normal vector drawing, for debug purposes onlynone: no normals drawn, we're being normal about itface: one normal per face drawnvertex: one normal per vertex drawn
rext(bool, default:true, updatable) — use the non-power-of-two (rectangular) texture GL extension ✨cull(bool, default:true, updatable) — use aabb culling: big objects get rendered in multiple calls when they're not fully in the viewportdepth_gl_scale(flt, default:100, updatable) — sets the depth scalerdepth_gl_type(enum, default:none, updatable) — the geometry type used to draw depth videonone: no geometric conversionpoint: compute a point cloud from pixel + depthstrip: same as point but it thins out the point set
nbviews(uint, default:0, updatable) — how many views to use in stereo modestereo(enum, default:none, updatable) — stereo output type. Heads up bestie: if your graphics card doesn't support OpenGL shaders, only the top and side modes will be available 💀none: no stereoside: images displayed side by side, left to righttop: images displayed top (laft view) to bottom (right view)hmd: same as side, except the view aspect ratio is not changedana: standard color anaglyph (red for left view, green and blue for right view) is used (forces views=2)cols: images interleaved by columns, left view on even columns and left view on odd columns (forces views=2)rows: images interleaved by columns, left view on even rows and left view on odd rows (forces views=2)spv5: images interleaved for SpatialView 5 views display, fullscreen mode (forces views=5)alio8: images interleaved for Alioscopy 8 views displays, fullscreen mode (forces views=8)custom: images interleaved according to the shader file indicated in mvshader. The shader is exposed to each view as uniformsampler2D gfViewX, where X is the view number starting from the left
mvshader(str, updatable) — file path to the custom multiview interleaving shader 🎀fpack(enum, default:none, updatable) — default frame packing of the input videonone: no frame packingtop: top bottom frame packingside: side by side packing
camlay(enum, default:offaxis, updatable) — camera layout in multiview modesstraight: camera moved along a straight line, no rotationoffaxis: off-axis projection is usedlinear: camera moved along a straight line with rotationcircular: camera moved along a circle with rotation
iod(flt, default:6.4, updatable) — inter-ocular distance (eye separation) in cm, aka the distance between the cameras 👀rview(bool, default:false, updatable) — reverse the view orderdbgpack(bool, default:false, updatable) — view packed stereo video as a single image (show all)tvtn(uint, default:30, updatable) — number of point sampling for the tile visibility algorithmtvtt(uint, default:8, updatable) — number of points above which the tile is considered visibletvtd(enum, default:off, updatable) — debug tiles and full coverage SRDoff: regular drawpartial: only displaying partial tiles, not the full sphere videofull: only display the full sphere video
tvtf(bool, default:false, updatable) — force all tiles to be considered visible, regardless of viewpoint, no thoughts head emptyfov(flt, default:1.570796326794897, updatable) — default field of view for VRvertshader(str) — path to vertex shader filefragshader(str) — path to fragment shader fileautocal(bool, default:false, updatable) — auto calibration ofznear/zfarin depth rendering modedispdepth(sint, default:-1, updatable) — display depth; a negative value uses the default screen heightdispdist(flt, default:50, updatable) — distance in cm between the camera and the zero-disparity plane. Just so you know: there is currently no automatic calibration of depth in GPACfocdist(flt, default:0, updatable) — distance of focus pointosize(v2di, default:0x0, updatable) — force output size. If it's not set, the size is derived from the inputsdpi(v2di, default:96x96, updatable) — default dpi if it's not indicated by the video outputdbgpvr(flt, default:0, updatable) — debug scene used by PVR addonplayer(enum, default:no) — set compositor in player modeno: regular modebase: player modegui: player mode with GUI auto-start
noaudio(bool, default:false) — disable audio output 🔇opfmt(pfmt, default:none, Enum:none|yuv420|yvu420|yuv420_10|yuv422|yuv422_10|yuv444|yuv444_10|uyvy|vyuy|yuyv|yvyu|uyvl|vyul|yuyl|yvyl|nv12|nv21|nv1l|nv2l|yuva|yuvd|yuv444a|yuv444p|v308|yuv444ap|v408|v410|v210|grey|algr|gral|rgb8|rgb4|rgb5|rgb6|rgba|argb|bgra|abgr|rgb|bgr|xrgb|rgbx|xbgr|bgrx|rgbd|rgbds|uncv) — pixel format to use for output. Ignored in player modedrv(enum, default:auto) — indicate if the graphics driver should be usedno: never loads a graphics driver, software blit is used, no 3D possible (in player mode, disables OpenGL)yes: always loads a graphics driver, output pixel format will be RGB (in player mode, same as auto)auto: decides based on the loaded content
src(cstr) — URL of source contentgaze_x(sint, default:0, updatable) — horizontal gaze coordinate (0=left, width=right)gaze_y(sint, default:0, updatable) — vertical gaze coordinate (0=top, height=bottom)gazer_enabled(bool, default:false, updatable) — enable gaze event dispatchsubtx(sint, default:0, updatable) — horizontal translation in pixels towards right for subtitles rendererssubty(sint, default:0, updatable) — vertical translation in pixels towards top for subtitles rendererssubfs(uint, default:0, updatable) — font size for subtitles renderers (0means automatic)subd(sint, default:0, updatable) — subtitle delay in milliseconds for subtitles renderersaudd(sint, default:0, updatable) — audio delay in millisecondsclipframe(bool, default:false) — visual output is clipped to bounding rectangle ✂️
🎬 mp4dmx
Description 💖
ISOBMFF/QT demultiplexer
This filter demultiplexes ISOBMF and QT files. The input ISOBMFF/QT can be regular or fragmented, and available as files or as raw bytestream. It's giving versatile, honestly.
Track Selection 🌸
The filter can use fragment identifiers of the source to select a single track for playback. The allowed fragments are:
#audio: only use the first audio track#video: only use the first video track#auxv: only use the first auxiliary video track#pict: only use the first picture track#text: only use the first text track#trackID=VAL: only use the track with given ID#itemID=VAL: only use the item with given ID#ID=VAL: only use the track/item with given ID#VAL: only use the track/item with given ID
Scalable Tracks 👑
When scalable tracks are present in a file, the reader can operate in 3 modes using the smode option:
smode=single: resolves all extractors to extract a single bitstream from a scalable set. The highest level is used. In this mode, there is no enhancement decoder config — only a base one resulting from the merge of the layers configurations.smode=split: all extractors are removed and every track of the scalable set is declared. In this mode, each enhancement track has no base decoder config and an enhancement decoder config.smode=splitx: extractors are kept in the bitstream, and every track of the scalable set is declared. In this mode, each enhancement track has a base decoder config (copied from base) and an enhancement decoder config. This is mostly used for DASHing content.
⚠️ Warning bestie: smode=splitx will result in extractor NAL units still present in the output bitstream, which shall only be true if the output is ISOBMFF based 💀
src(cstr) — local file name of the source content, and ngl this one's only used when you're explicitly loading the filter, so like, don't expect it to do anything otherwise 💅allt(bool, default:false) — load all the tracks even if the media type is unknown, bestie. no gatekeeping here.edits(enum, default:auto) — do not use edit lists (the drama of it all):auto— track delay and no edit list when possible ✨no— ignore edit list entirelystrict— use the edit list even if it's only signaling a delay
itt(bool, default:false) — convert all items of root meta into a single PID. one PID to rule them all fr.itemid(bool, default:true) — keep item IDs in PID properties, lowkey important for iykyk reasons 💖smode(enum, default:split) — load mode for scalable/tile tracks, choose ur fighter:split— each track is declared, extractors are removedsplitx— each track is declared, extractors are keptsingle— a single track is declared (highest level for scalable, tile base for tiling)
alltk(bool, default:false) — declare disabled tracks. yes, even the shy ones 🫶frame_size(uint, default:1024) — frame size for raw audio samples (it dispatchesframe_sizesamples per packet, periodt)expart(bool, default:false) — expose cover art as a dedicated video PID. album art gets main character energy now 🌸sigfrag(bool, default:false) — signal fragment and segment boundaries of the source on output packets, and heads up: it fails if the source is not fragmented 💀tkid(str) — declare only the track based on the given param:- integer value — declares the track with the given ID
audio— declares the first audio trackvideo— declares the first video track4CC— declares the first track with matching 4CC for handler type
stsd(uint, default:0) — only extract the sample mapped to the given sample description index (0means extract all of them, the whole buffet)nocrypt(bool) — signal encrypted tracks as non encrypted, mostly used for export. sneaky but valid 🙈mstore_size(uint, default:1000000) — target buffer size in bytes when reading from a memory stream (pipe etc...)mstore_purge(uint, default:50000) — minimum size in bytes between memory purges when reading from a memory stream.0means purge as soon as possible, no chill at all.mstore_samples(uint, default:50) — minimum number of samples that gotta be present before purging sample tables when reading from a memory stream (pipe etc...).0means purge as soon as possible.strtxt(bool, default:false) — load text tracks (apple/tx3g) as MPEG-4 streaming text tracksxps_check(enum, default:auto) — parameter sets extraction mode from AVC/HEVC/VVC samples:keep— do not inspect sample (assumes input file is compliant when generating DASH/HLS/CMAF)rem— removes all inband xPS and notifies configuration changes accordinglyauto— resolves tokeepforsmode=splitx(dasher mode),remotherwise
nodata(enum, default:no) — control sample data loading:no— regular loadyes— skip data loadingfake— allocate sample but no data copy
lightp(bool, default:false) — load minimal set of properties, the bare minimum erainitseg(str) — local init segment name when input is a single ISOBMFF segmentextk(bool, default:true) — allow external track loadingctso(sint) — value to add to the CTS offset for tracks using negative ctts:- set to
-1to use thecslgbox info or the minimum cts offset present in the track - set to
-2to use the minimum cts offset present in the track (cslgignored)
- set to
norw(bool, default:false) — skip reformatting of samples — should only be used when rewriting fragments, okay? only then.keepc(bool, default:true) — keep corrupted samples (for multicast sources only)
🦋 bifsdec 🦋
Description: MPEG-4 BIFS decoder
This filter decodes MPEG-4 BIFS binary frames directly into the scene graph of the compositor. iconic behaviour honestly ✨
Note: this filter cannot be used to dump BIFS content to text or xml — use MP4Box for that, bestie. different tool, different job 💅
No options
🌈 odfdec 🌈
Description: MPEG-4 OD decoder
This filter decodes MPEG-4 OD binary frames directly into the scene manager of the compositor.
Note: this filter cannot be used to dump OD content to text or xml — use MP4Box for that.
No options
🎀 fin 🎀
Description: File input
This filter dispatches raw blocks from an input file into a filter chain. Block size can be adjusted using block_size. Content format can be forced through mime and the file extension can be changed through ext.
Note: unless disabled at session level (see -no-probe), file extensions are usually ignored and format probing is done on the first data block. so like, don't trust the extension, trust the vibes 🔍
The special file name null is used for creating a file with no data, needed by some filters such as dasher.
The special file name rand is used to generate random data.
The special file name randsc is used to generate random data with 0x000001 start-code prefix.
The filter handles both files and GF_FileIO objects as input URL.
💌 Packet Injecting 💌
The filter can be used to inject a single packet instead of a file using pck option.
No specific properties are attached, except a timescale if ptime is set.
Example
gpac fin:pck=str@"My Sample
Text":ptime=2500/100:#CodecID=stxt:#StreamType=text
This will declare the PID as WebVTT and send a single packet with payload My Sample Text and a timestamp value of 25 second. slay 💅
Options (expert):
src(cstr) — location of source fileblock_size(uint, default:0) — block size used to read file.0means5000if file less than 500m,1Motherwiserange(lfrac, default:0-0) — byte rangeext(cstr) — override file extensionmime(cstr) — set file mime typepck(mem) — data to use instead of fileptime(frac, default:0/0) — timing for data packet, ignored if den is0
🧚 btplay 🧚
Description: BT/XMT/X3D decoder
This filter parses MPEG-4 BIFS (BT and XMT), VRML97 and X3D (wrl and XML) files directly into the scene graph of the compositor. no cap.
When sax_dur is set to N, the filter will do a progressive load of the source and cancel the current loading when processing time is higher than N. it's giving patience 💅
Options (expert):
sax_dur(uint, default:0) — duration for SAX parsing (XMT),0disables SAX parsing
🌸 httpin 🌸
Description: HTTP input
This filter dispatches raw blocks from a remote HTTP resource into a filter chain. Block size can be adjusted using block_size, and disk caching policies can be adjusted. Content format can be forced through mime and file extension can be changed through ext.
The filter supports both http and https schemes, and will attempt reconnecting as TLS if the TCP connection fails. resilient queen 👑
Note: unless disabled at session level (see -no-probe), file extensions are usually ignored and format probing is done on the first data block.
Options (expert):
src(cstr) — URL of source contentblock_size(uint, default:100000) — block size used to read filecache(enum, default:none) — set cache mode:auto— cache to disk if content length is known, no cache otherwisedisk— cache to disk, discard once session is no longer usedkeep— cache to disk and keepmem— stores to memory, discard once session is no longer usedmem_keep— stores to memory, keep after session is reassigned but move tomemafter first downloadnone— no cachenone_keep— stores to memory, keep after session is reassigned but move tononeafter first download
range(lfrac, default:0-0) — set byte range, as fractionext(cstr) — override file extensionmime(cstr) — set file mime typeblockio(bool, default:false) — use blocking IOidelay(uint, default:0) — delay first request by the given number of ms. fashionably late ✨
💜 svgplay 💜
Description: SVG decoder
This filter parses SVG files directly into the scene graph of the compositor.
When sax_dur is set to N, the filter will do a progressive load of the source and cancel the current loading when processing time is higher than N.
Options (expert):
sax_dur(uint, default:0) — loading duration for SAX parsing,0disables SAX parsing
🍓 rfimg 🍓
Description: JPG/J2K/PNG/BMP reframer
This filter parses JPG/J2K/PNG/BMP files/data and outputs the corresponding visual PID and frames. serving looks 👑
The following extensions for PNG change the pixel format for RGBA images:
pngd— use RGB+depth map pixel formatpngds— use RGB+depth(7bits)+shape(MSB of alpha channel) pixel format
No options
⭐ imgdec ⭐
Description: PNG/JPG decoder
This filter decodes JPEG and PNG images.
No options
🎀 rfadts 🎀
Description: ADTS reframer
This filter parses AAC files/data and outputs the corresponding audio PID and frames.
Options (expert):
frame_size(uint, default:1024) — size of AAC frame in audio samplesindex(dbl, default:1.0) — indexing window lengthovsbr(bool, default:false) — force oversampling SBR (does not multiply timescales by2)sbr(enum, default:no) — set SBR signaling:no— no SBR signaling at allimp— backward-compatible SBR signaling (audio signaled as AAC-LC)exp— explicit SBR signaling (audio signaled as AAC-SBR)
ps(enum, default:no) — set PS signaling:no— no PS signaling at allimp— backward-compatible PS signaling (audio signaled as AAC-LC)exp— explicit PS signaling (audio signaled as AAC-PS)
expart(bool, default:false) — expose pictures as a dedicated video PIDaacchcfg(sint, default:0) — set AAC channel configuration to this value if missing from the ADTS header, use a negative value to always override
🦋 rflatm 🦋
Description: LATM reframer
This filter parses AAC in LATM files/data and outputs the corresponding audio PID and frames.
Options (expert):
frame_size(uint, default:1024) — size of AAC frame in audio samplesindex(dbl, default:1.0) — indexing window length
🌈 rfmp3 🌈
Description: MP3 reframer
This filter parses MPEG-1/2 audio files/data and outputs the corresponding audio PID and frames.
Options (expert):
index(dbl, default:1.0) — indexing window lengthexpart(bool, default:false) — expose pictures as a dedicated video PIDforcemp3(bool, default:true) — force mp3 signaling for MPEG-2 Audio layer 3
🧚 faad 🧚
Description: FAAD decoder
This filter decodes AAC streams through the faad library.
No options
💅 maddec 💅
Description: MAD decoder
This filter decodes MPEG 1/2 audio streams through the libmad library.
No options
🔥 xviddec 🔥
Description: XVid decoder
This filter decodes MPEG-4 part 2 (and DivX) through the libxvidcore library.
Options (expert):
deblock_y(bool, default:false) — enable Y deblockingdeblock_uv(bool, default:false) — enable UV deblockingfilm_effect(bool, default:false) — enable film effectdering_y(bool, default:false) — enable Y deblockingdering_uv(bool, default:false) — enable UV deblocking
👑 j2kdec 👑
Description: OpenJPEG2000 decoder
Version: 2.x
This filter decodes JPEG2000 streams through the OpenJPEG2000 library.
No options
rfac3 💜
Description: AC3 reframer
This filter parses AC3 and E-AC3 files/data and outputs corresponding audio PID and frames. It's giving audio-translator energy, bestie 🎀
Options (expert) ✨
index(dbl, default:1.0) — indexing window length
rfac4 🌸
Description: AC4 reframer
This filter parses AC4 files/data and outputs corresponding audio PID and frames. Same vibe as rfac3 but make it AC4 💅
No options — she's low maintenance, fr fr.
ufac4 🦋
Description: AC4 writer
This filter converts MPEG-H Audio streams into AC4 encapsulated data. Literally the reverse glow-up 😭✨
Options (expert) ✨
rcfg(bool, default:true) — force repeating decoder config at each I-frame
a52dec 💖
Description: A52 decoder
This filter decodes AC3 streams through a52dec library.
No options — no knobs, no drama, just decoding 👑
rfamr 🎀
Description: AMR/EVRC reframer
This filter parses AMR, AMR Wideband, EVRC and SMV files/data and outputs corresponding audio PID and frames. So many codecs in one filter, she's a multitasker 💅
Options (expert) ✨
index(dbl, default:1.0) — indexing window length
oggdmx 🌈
Description: OGG demultiplexer
This filter demultiplexes OGG files/data into a set of media PIDs and frames. Splitting the ogg into its little component besties 🫶
Options (expert) ✨
index(dbl, default:1.0) — indexing window length (not implemented), use0to disable stream probing for durationexpart(bool, default:false) — expose pictures as a dedicated video PID
vorbisdec ⭐
Description: Vorbis decoder
This filter decodes Vorbis streams through libvorbis library.
No options 🎶
theoradec 💜
Description: Theora decoder
This filter decodes Theora streams through libtheora library.
No options 🎬
m2tsdmx 🧚
Description: MPEG-2 TS demultiplexer
This filter demultiplexes MPEG-2 Transport Stream files/data into a set of media PIDs and frames. The classic. The icon. The moment 👑
Options (expert) ✨
temi_url(cstr) — force TEMI URLdsmcc(bool, default:no) — enable DSMCC receiverseeksrc(bool, default:true) — seek local source file back to origin once all programs are setupsigfrag(bool, default:false) — signal segment boundaries on output packets for DASH or HLS sourcesdvbtxt(bool, default:false) — export DVB teletext streamsupes(enum, default:no) — keep unknown PES streamsno— ignored the streamsinfo— declare the stream as fake (no data forward), turns ondvbtxtfull— declare the stream and sends data
mappcr(bool, default:true) — remap PCR and timestamps into continuous timeline
sockin 💖
Description: UDP/TCP input
This filter handles generic TCP and UDP input sockets. It can also probe for MPEG-2 TS over RTP input. Probing of MPEG-2 TS over UDP/RTP is enabled by default but can be turned off. Bestie, she's literally the door greeter for your network packets 🚪✨
Data format can be specified by setting either ext or mime options. If not set, the format will be guessed by probing the first data packet.
- UDP sockets are used for source URLs formatted as
udp://NAME - TCP sockets are used for source URLs formatted as
tcp://NAME - UDP unix domain sockets are used for source URLs formatted as
udpu://NAME - TCP unix domain sockets are used for source URLs formatted as
tcpu://NAME
When ports are specified in the URL and the default option separators are used (see gpac -h doc), the URL must either:
- have a trailing
/, e.g.udp://localhost:1234/[:opts] - use gpac separator, e.g.
udp://localhost:1234[:gpac:opts]
When the socket is listening in keep-alive ka mode:
- a single connection is allowed and a single output PID will be produced
- each connection close event will triger a pipeline flush
On OSX with VM packet replay you will need to force multicast routing, e.g. route add -net 239.255.1.4/32 -interface vboxnet0
Time Regulation ⏰
The filter uses the time between the last two received packets to estimates how often it should check for inputs. The maximum and minimum times to wait between two calls is given by the mwait option. The maximum time may need to be reduced for very high bitrates sources. So if your bitrate is eating, turn that wait time down 💀
Options (expert) ✨
src(cstr) — address of source contentblock_size(uint, default:0x60000) — block size used to read socketport(uint, default:1234) — default port if not specifiedifce(cstr) — default multicast interfacelisten(bool, default:false) — indicate the input socket works in server modeka(bool, default:false) — keep socket alive if no more connectionsmaxc(uint, default:+I) — max number of concurrent connectionstsprobe(bool, default:true) — probe for MPEG-2 TS data, either RTP or raw UDP. Disabled ifmimeorextare given and do not match MPEG-2 TS mimes/extensionsext(str) — indicate file extension of udp datamime(str) — indicate mime type of udp datablock(bool, default:false) — set blocking mode for socket(s)timeout(uint, default:10000) — set timeout in ms for UDP socket(s),0to disable timeoutmwait(v2di, default:1x30) — set min and max wait times in ms to avoid too frequent pollingreorder_pck(uint, default:100) — number of packets delay for RTP reordering (M2TS over RTP)reorder_delay(uint, default:10) — number of ms delay for RTP reordering (M2TS over RTP)ssm(strl) — list of IP to include for source-specific multicastssmx(strl) — list of IP to exclude for source-specific multicast
dvbin 📺
Description: DVB for Linux
This filter reads raw MPEG-2 TS from DVB-T/T2 and DVB-S/S2 cards on linux. Penguin-coded, no cap 🐧
The URL scheme used is dvb:// with the following syntaxes:
`dvb://CHAN`— tunes to channel CHAN in the channel configuration file.`dvb://+CHAN`— tunes to multiplex contaning channel CHAN and expose all programs.`dvb://=N`— tunes to the N-th channel in the channel configuration file.`dvb://@FREQ`— tunes to frequency FREQ and exposes all channels in multiplex.`dvb://@=N`— tunes to N-th frequency and exposes all channels in multiplex.`dvb://@chlist`— populates the chans option with available channels in the configuration file and do nothing else.
When tuning by channel name CHAN, the first entry in the channel configuration file starting with CHAN will be used.
The channel configuration file is set through chcfg. The expected format is VDR as produced by w_scan, with a syntax extended for comment lines, starting with #. Within a comment line, the following keywords can be used to override defaults:
`dev=N`— set the adapter index (N integer) or full path (N string).`idx=K`— set the frontend index K.`csidx=S`— set the committed switch index for DiSEqC.
To view the default channels, use gpac -hx dvbin. Peek at the goods 👀
Options (expert) ✨
src(cstr) — URL of source contentblock_size(uint, default:65536) — block size used to read devicechcfg(cstr, default:$GCFG/channels.conf) — path to channels configuration filedev(str, default:0) — path to DVB adapter - if first character is a number, this is the device indexidx(uint, default:0) — frontend indextimeout(uint, default:5000) — timeout in ms before tune failurecsleep(uint, default:15) — config sleep in ms between DiSEqC commandscsidx(uint, default:0) — committed switch index for DiSEqCchans(strl) — list of all channels, only pupulated fordvb://@chlistURL
osvcdec 💜
Description: OpenSVC decoder
This filter decodes scalable AVC|H264 streams through OpenSVC library.
No options — scalable and silent, main character energy 💅
vtbdec 🔥
Description: VideoToolBox decoder
This filter decodes video streams through OSX/iOS VideoToolBox (MPEG-2, H263, AVC|H264, HEVC, ProRes). It allows GPU frame dispatch or direct frame copy. Apple girlies, this one's for you 🍎✨
Options (expert) ✨
reorder(uint, default:6) — number of frames to wait for temporal re-orderingno_copy(bool, default:true) — dispatch decoded frames as OpenGL textures (true) or as copied packets (false)ofmt(pfmt, default:nv12) — set default pixel format for decoded video. If not found, fall back tonv12disable_hw(bool, default:false) — disable hardware decodingwait_sync(bool, default:false, updatable) — wait for sync frame before decoding
mcdec 📱
Description: MediaCodec decoder
This filter decodes video streams using hardware decoder on android devices. Android besties rise 🙈
Options (expert) ✨
disable_gl(bool, default:false) — disable OpenGL texture transfer
lsrdec 🎀
Description: MPEG-4 LASeR decoder
This filter decodes MPEG-4 LASeR binary frames directly into the scene graph of the compositor.
Note: This filter cannot be used to dump LASeR content to text or xml, use MP4Box for that. So don't come for her about dumping, that's literally not her job 😭
No options
safdmx 🧚
Description: SAF demultiplexer
This filter demultiplexes SAF (MPEG-4 Simple Aggregation Format for LASeR) files/data into a set of media PIDs and frames.
No options ✨
dashin 🌈
Description: DASH & HLS client
This filter reads MPEG-DASH, HLS and MS Smooth manifests. The streaming queen herself, she contains multitudes 👑
Regular mode 💖
This is the default mode, in which the filter produces media PIDs and frames from sources indicated in the manifest.
The default behavior is to perform adaptation according to algo, but the filter can:
- run with no adaptation, to grab maximum quality.
Example
gpac -i MANIFEST_URL:algo=none:start_with=max_bw -o dest.mp4
- run with no adaptation, fetching all qualities.
Example
gpac -i MANIFEST_URL:split_as -o dst=$File$.mp4
File mode 📁
When forward is set to file, the client forwards media files without demultiplexing them.
This is mostly used to expose the DASH session to a file server such as ROUTE or HTTP.
In this mode, the manifest is forwarded as an output PID.
Warning: This mode cannot be set through inheritance as it changes the link capabilities of the filter. The filter MUST be explicitly declared. No sneaky inheriting, bestie, she will not allow it 💀
To expose a live DASH session to route:
gpac -i MANIFEST_URL dashin:forward=file -o route://225.0.0.1:8000/
If the source has dependent media streams (scalability) and all qualities and initialization segments need to be forwarded, add split_as.
🎀 Segment bound modes 🎀
When forward is set to segb or mani, the client forwards media frames (after demultiplexing, bestie) together with segment and fragment boundaries of source files. 💖
This mode can be used to process media data and regenerate the same manifest/segmentation. no cap.
Example:
gpac -i MANIFEST_URL:forward=mani cecrypt:cfile=DRM.xml -o encrypted/live.mpd:pssh=mv
This will encrypt an existing DASH session, inject PSSH in manifest and segments. 🔥
Example:
gpac -i MANIFEST_URL:forward=segb cecrypt:cfile=DRM.xml -o encrypted/live.m3u8
This will encrypt an existing DASH session and republish it as HLS, using same segment names and boundaries. iconic behavior honestly.
This mode will force noseek=true to ensure the first segment fetched is complete, and split_as=true to fetch all qualities.
Each first packet of a segment will have the following properties attached:
CueStart: indicate this is a segment startFileNumber: current segment numberFileName: current segment file name without manifest (MPD or master HLS) base urlDFPStart: set with value 0 if this is the first packet in the period, absent otherwise
If forward is set to mani, the first packet of a segment dispatched after a manifest update will also carry the manifest payload as a property:
DFManifest: contains main manifest (MPD, M3U8 master)DFVariant: contains list of HLS child playlists as strings for the given qualityDFVariantName: contains list of associated HLS child playlists name, in same order as manifests in DFVariant
Each output PID will have the following properties assigned:
DFMode: set to 1 for segb or 2 for maniDCue: set to inbandDFPStart: set to current period start valueFileName: set to associated init segment if anyRepresentation: set to the associated representation ID in the manifestDashDur: set to the average segment duration as indicated in the manifestsource_template: set to true to indicate the source template is knownstl_timescale: timescale used by SegmentTimeline, or 0 if no SegmentTimelineinit_url: unresolved intialization URL (as it appears in the MPD or in the variant playlist)manifest_url: manifest URLhls_variant_name: HLS variant playlist name (as it appears in the HLS master playlist)
When the dasher is used together with this mode, this will force all generated segments to have the same name, duration and fragmentation properties as the input ones. It is therefore not recommended for sessions stored/generated on local storage to generate the output in the same directory. ⚠️
✨ Options (expert): ✨
auto_switch(sint, default: 0): switch quality every N segments- positive: go to higher quality or loop to lowest
- negative: go to lower quality or loop to highest
- 0: disabled
segstore(enum, default: mem): enable file caching- mem: all files are stored in memory, no disk IO
- disk: files are stored to disk but discarded once played
- cache: all files are stored to disk and kept
algo(str, default: gbuf, Enum:none|grate|gbuf|bba0|bolaf|bolab|bolau|bolao|JS): adaptation algorithm to use- none: no adaptation logic
- grate: GPAC legacy algo based on available rate
- gbuf: GPAC legacy algo based on buffer occupancy
- bba0: BBA-0
- bolaf: BOLA Finite
- bolab: BOLA Basic
- bolau: BOLA-U
- bolao: BOLA-O
- JS: use file JS (either with specified path or in
$GSHARE/scripts/) for algo (.jsextension may be omitted)
start_with(enum, default: max_bw): initial selection criteria- min_q: start with lowest quality
- max_q: start with highest quality
- min_bw: start with lowest bitrate
- max_bw: start with highest bitrate; if tiles are used, all low priority tiles will have the lower (below max) bandwidth selected
- max_bw_tiles: start with highest bitrate; if tiles are used, all low priority tiles will have their lowest bandwidth selected
max_res(bool, default: true): use max media resolution to configure displayabort(bool, default: false): allow abort during a segment downloaduse_bmin(enum, default: auto): playout buffer handling- no: use default player settings
- auto: notify player of segment duration if not low latency
- mpd: use the indicated min buffer time of the MPD
shift_utc(sint, default: 0): shift DASH UTC clock in msspd(sint, default: -I): suggested presentation delay in msmcast_shift(sint, default: 0): shift requests time by given ms for multicast sourcesserver_utc(bool, default: yes): use ServerUTC or Date HTTP headers instead of local UTCscreen_res(bool, default: yes): use screen resolution in selection phaseinit_timeshift(sint, default: 0): set initial timeshift in ms (if >0) or in per-cent of timeshift buffer (if <0)tile_mode(enum, default: none): tile adaptation mode- none: bitrate is shared equally across all tiles
- rows: bitrate decreases for each row of tiles starting from the top, same rate for each tile on the row
- rrows: bitrate decreases for each row of tiles starting from the bottom, same rate for each tile on the row
- mrows: bitrate decreased for top and bottom rows only, same rate for each tile on the row
- cols: bitrate decreases for each columns of tiles starting from the left, same rate for each tile on the columns
- rcols: bitrate decreases for each columns of tiles starting from the right, same rate for each tile on the columns
- mcols: bitrate decreased for left and right columns only, same rate for each tile on the columns
- center: bitrate decreased for all tiles on the edge of the picture
- edges: bitrate decreased for all tiles on the center of the picture
tiles_rate(uint, default: 100): indicate the amount of bandwidth to use at each quality level. The rate is recursively applied at each level, e.g. if 50%, Level1 gets 50%, level2 gets 25%, ... If 100, automatic rate allocation will be done by maximizing the quality in order of priority. If 0, bitstream will not be smoothed across tiles/qualities, and concurrency may happen between different mediadelay40X(uint, default: 500): delay in milliseconds to wait between two 40X on the same segmentexp_threshold(uint, default: 100): delay in milliseconds to wait after the segment AvailabilityEndDate before considering the segment lostswitch_count(uint, default: 1): indicate how many segments the client shall wait before switching up bandwidth. If 0, switch will happen as soon as the bandwidth is enough, but this is more prone to network variationsaggressive(bool, default: no): if enabled, switching algo targets the closest bandwidth fitting the available download rate. If no, switching algo targets the lowest bitrate representation that is above the currently played (e.g. does not try to switch to max bandwidth)debug_as(uintl): play only the adaptation sets indicated by their indices (0-based) in the MPDspeedadapt(bool, default: no): enable adaptation based on playback speednoxlink(bool, default: no): disable xlink if period has both xlink and adaptation setsquery(str): set query string (without initial'?') to append to xlink of periodssplit_as(bool, default: no): separate all qualities into different adaptation sets and stream all qualities. Dependent representations (scalable) are treated as independentnoseek(bool, default: no): disable seeking of initial segment(s) in dynamic mode (useful when UTC clocks do not match)bwcheck(uint, default: 5): minimum time in milliseconds between two bandwidth checks when allowing segment download abortlowlat(enum, default: early): segment scheduling policy in low latency mode- no: disable low latency
- strict: strict respect of AST offset in low latency
- early: allow fetching segments earlier than their AST in low latency when input PID is empty
forward(enum, default: none): segment forwarding mode- none: regular DASH read
- file: do not demultiplex files and forward them as file PIDs (imply
segstore=mem) - segb: turn on
split_as, segment and fragment bounds signaling (sigfrag) in sources and DASH cue insertion - mani: same as segb and also forward manifests
fmodefwd(bool, default: yes): forward packet rather than copy them in file forward mode. Packet copy might improve performances in low latency modeskip_lqt(bool, default: no): disable decoding of tiles with highest degradation hints (not visible, not gazed at) for debug purposesllhls_merge(bool, default: yes): merge LL-HLS byte range parts into a single open byte range requestgroupsel(bool, default: no): select groups based on language (by default all playable groups are exposed)xas(enum, default: codec): enable cross adaptation set switching (disabled ifsplit_asis set)- no: disabled
- codec: switching across sets only allowed for same codec
- all: switching across sets allowed across any representation types
chain_mode(enum, default: on): MPD chaining mode- off: do not use MPD chaining
- on: use MPD chaining once over, fallback if MPD load failure
- error: use MPD chaining once over or if error (MPD or segment download)
asloop(bool, default: false): when auto switch is enabled, iterates back and forth from highest to lowest qualitiesbsmerge(bool, default: true): allow merging of video bitstreams (only HEVC for now)keep_burl(enum, default: strip): control BaseURL in manifest- strip: strip BaseURL (default)
- keep: keep BaseURL
- inject: inject local relative URL before BaseURL value specified by
relative_urloption
relative_url(str, default:./): relative string to inject before BaseURL whenkeep_base_urlis set to inject
🦋 cdcrypt 🦋
Description: CENC decryptor
The CENC decryptor supports decrypting CENC, ISMA, HLS Sample-AES (MPEG2 ts) and Adobe streams. 💅
For HLS, key is retrieved according to the key URI in the manifest. Otherwise, the filter uses a configuration file. The syntax is available at https://wiki.gpac.io/xmlformats/Common-Encryption
The DRM config file can be set per PID using the property DecryptInfo (highest priority), CryptInfo (lower priority) or set at the filter level using cfile (lowest priority). When the file is set per PID, the first CryptInfo with the same ID is used, otherwise the first CryptInfo is used. When the file is set globally (not per PID), the first CrypTrack in the DRM config file with the same ID is used, otherwise the first CrypTrack with ID 0 or not set is used. 🎀
✨ Options (expert): ✨
cfile(str) — where the crypt file lives 💖decrypt(enum, default:full) — the decrypt mode (CENC only, bestie)full— decrypt literally everything, and throw an error if the keys aren't found 😭nokey— decrypt everything you do have a key for, and skip decryption otherwiseskip— decrypt nothing at all, we're just vibingpad0— decrypt nothing and replace all crypted bits with0pad1— decrypt nothing and replace all crypted bits with1padsc— decrypt nothing and replace all crypted bytes with start codes
drop_keys(uintl) — treat keys with the given 1-based indexes as not available (multi-key debug szn)kids(strl) — define KIDs. Ifkeysis empty, treat keys with the given KID (as hex string) as not available (debug)keys(strl) — define key values for each of the specified KIDhls_cenc_patch_iv(bool, default:false) — ignore IV updates in some broken HLS+CENC streams 🙈
🧚 cecrypt 🧚
Description: CENC encryptor
The CENC encryptor supports CENC, ISMA and Adobe encryption. It uses a DRM config file for declaring keys, periodt. 🔐
The syntax is available at https://wiki.gpac.io/xmlformats/Common-Encryption
The DRM config file can be set per PID using the property CryptInfo, or set at the filter level using cfile.
When the DRM config file is set per PID, the first CrypTrack in the DRM config file with the same ID is used, otherwise the first CrypTrack is used (regardless of the CrypTrack ID).
When the DRM config file is set globally (not per PID), the first CrypTrack in the DRM config file with the same ID is used, otherwise the first CrypTrack with ID 0 or not set is used.
If no DRM config file is defined for a given PID, this PID will not be encrypted, or an error will be thrown if allc is specified. Pick your fighter wisely 💀
✨ Options (expert): ✨
cfile(str) — crypt file locationallc(bool) — throw error if no DRM config file is found for a PIDbk_stats(bool) — print number of encrypted blocks to stdout upon exitbk_skip(bool) — skip encryption but performs all other tasks (test mode)
🎀 mp4mx 🎀
Description: ISOBMFF/QT multiplexer
This filter multiplexes streams to ISOBMFF (14496-12 and derived specifications) or QuickTime. It's giving container-wrangler, no cap. 🫶
📦 Tracks and Items 📦
By default all input PIDs with ItemID property set are multiplexed as items, otherwise they are multiplexed as tracks.
To prevent source items to be multiplexed as items, use -itemid option from ISOBMFF demultiplexer.
Example
gpac -i source.mp4:itemid=false -o file.mp4
To force non-item streams to be multiplexed as items, use #ItemID option on that PID:
gpac -i source.jpg:#ItemID=1 -o file.mp4
💾 Storage 💾
The store option allows controlling if the file is fragmented or not, and when not fragmented, how interleaving is done. For cases where disk requirements are tight and fragmentation cannot be used, it is recommended to use either flat or fstart modes. Your disk will thank you bestie ✨
The vodcache option allows controlling how DASH onDemand segments are generated:
- If set to
on, file data is stored to a temporary file on disk and flushed upon completion, no padding is present. - If set to
insert,SIDX/SSIXwill be injected upon completion of the file by shifting bytes in file. In this case, no padding is required but this might not be compatible with all output sinks and will take longer to write the file. - If set to
replace,SIDX/SSIXsize will be estimated based on duration and DASH segment length, and padding will be used in the file before the finalSIDX. If input PIDs have the propertiesDSegsset, this will used be as the number of segments.
The on and insert modes will produce exactly the same file, while the mode replace may inject a free box before the sidx.
🎁 Custom boxes 🎁
Custom boxes can be specified as box patches:
For movie-level patch, the boxpatch option of the filter should be used.
Per PID box patch can be specified through the PID property boxpatch.
Example
gpac -i source:#boxpatch=myfile.xml -o mux.mp4
Per Item box patch can be specified through the PID property boxpatch.
Example
gpac -i source:1ItemID=1:#boxpatch=myfile.xml -o mux.mp4
The box patch is applied before writing the initial moov box in fragmented mode, or when writing the complete file otherwise.
The box patch can either be a filename or the full XML string.
🏷️ Tagging 🏷️
When tagging is enabled, the filter will watch the property CoverArt and all custom properties on incoming PID.
The built-in tag names are indicated by MP4Box -h tags.
QT tags can be specified using qtt_NAME property names, and will be added using formatting specified in MP4Box -h tags.
Other tag class may be specified using tag_NAME property names, and will be added if itags is set to all using:
NAMEas a box 4CC ifNAMEis four characters longNAMEas a box 4CC ifNAMEis 3 characters long, and will be prefixed by0xA9- the CRC32 of the
NAMEas a box 4CC ifNAMEis not four characters long
Property names formatted as cust_NAME@MEAN are added as a custom tag with name NAME and mean MEAN. Both NAME and MEAN can be empty. iconic honestly 💅
🙋 User data 🙋
The filter will look for the following PID properties to create user data entries:
udtab: set the track user-data box to the property value which must be a serialized box array blobmudtab: set the movie user-data box to the property value which must be a serialized box array blobudta_U4CC: set track user-data box entry of typeU4CCto property valuemudta_U4CC: set movie user-data box entry of typeU4CCto property valuetkgp_T4CC: set/remove membership to track group with typeT4CCand ID given by property value. A negative valueNremoves from track group with ID-N
Example
gpac -i src.mp4:#udta_tagc='My Awesome Tag' -o tag.mp4
gpac -i src.mp4:#mudtab=data@box.bin -o tag.mp4
🧬 Custom sample group descriptions and sample auxiliary info 🧬
The filter watches the following custom data properties on incoming packets:
grp_A4CC: maps packet to sample group description of typeA4CCand entry set to property payloadgrp_A4CC_param: same as above and sets sample to groupgrouping_type_parametertoparamsai_A4CC: adds property payload as sample auxiliary information of typeA4CCsai_A4CC_param: same as above and setsaux_info_type_parametertoparam
The property grp_EMSG consists in one or more EventMessageBox as defined in MPEG-DASH.
- in fragmented mode, presence of this property in a packet will start a new fragment, with the boxes written before the
moof - in regular mode, an internal sample group of type
EMSGis currently used foremsgbox storage
📝 Notes 📝
The filter watches the property FileNumber on incoming packets to create new files (regular mode) or new segments (DASH mode).
The filter watches the property DSIWrap (4CC as int or string) on incoming PID to wrap decoder configuration in a box of given type (unknown wrapping)
Example
-i unkn.mkv:#ISOMSubtype=VIUK:#DSIWrap=cfgv -o t.mp4
This will wrap the unknown stream using VIUK code point in stsd and wrap any decoder configuration data in a cfgv box. so satisfying fr fr ✨
If pad_sparse is set, the filter watches the property Sparse on incoming PID to decide whether empty packets should be injected to keep packet duration info.
Such packets are only injected when a whole in the timeline is detected.
- if
Sparseis absent, empty packet is inserted for unknown text and metadata streams - if
Sparseistrue, empty packet is inserted for all stream types - if
Sparseisfalse, empty packet is never injected
The default media type used for a PID can be overridden using property StreamSubtype.
Example
-i src.srt:#StreamSubtype=sbtl [-i ...] -o test.mp4
This will force the text stream to use sbtl handler type instead of default text one.
Subtitle streams may be used as chapters by setting the property IsChap on the desired PID.
Example
-i src.srt:#IsChap [-i ...] -o test.mp4
This will force the text stream to be used as a QT chapter track.
✨ Options (expert): ✨
m4sys(bool, default:false) — force MPEG-4 Systems signaling of tracksdref(bool, default:false) — only reference data from source file — not compatible with all media sourcesctmode(enum, default:auto) — set composition offset mode for video tracksauto— if fragmenting an ISOBMFF source, use source settings otherwise resolve toeditedit— uses edit lists to shift first frame to presentation time0noedit— ignore edit lists and does not shift timelinenegctts— usescttsv1 with possibly negative offsets and no edit lists
dur(frac, default:0) — only import the specified duration. If negative, specify the number of coded frames to importpack3gp(uint, default:1) — pack a given number of 3GPP audio frames in one sampleimporter(bool, default:false) — compatibility with old importer, displays import progresspack_nal(bool, default:false) — repack NALU size length to minimum possible size for NALU-based video (AVC/HEVC/...)xps_inband(enum, default:no) — use inband (in sample data) parameter set for NALU-based video (AVC/HEVC/...)no— parameter sets are not inband, several sample descriptions might be createdpps— picture parameter sets are inband, all other parameter sets are in sample descriptionall— parameter sets are inband, no parameter sets in sample descriptionboth— parameter sets are inband, signaled as inband, and also first set is kept in sample descriptionmix— creates non-standard files using single sample entry with first PSs found, and moves other PS inbandauto— keep source config, or defaults tonoif source is not ISOBMFF
store(enum, default:inter) — file storage modeinter— perform precise interleave of the file usingcdur(requires temporary storage of all media)flat— write samples as they arrive andmoovat end (fastest mode)fstart— write samples as they arrive andmoovbeforemdattight— uses per-sample interleaving of all tracks (requires temporary storage of all media)frag— fragments the file usingcdurdurationsfrag— fragments the file usingcdurduration but adjusting to start with SAP1/3
cdur(frac, default:-1/1) — chunk duration forflatand interleaving modes or fragment duration for fragmentation modes0— no specific interleaving butmoovfirst- negative — defaults to
1.0unless overridden by storage profile
moovts(sint, default:600) — timescale for the movie 🎬. Give it a negative value and it just snags the media timescale off the first track you add. easy.moof_first(bool, default:true) — frags start withmoof, thenmdat. order matters bestie ✨abs_offset(bool, default:false) — use absolute file offset inside fragments instead of offsets measured frommoof.fsap(bool, default:true) — split truns in video fragments at SAPs so the file doesn't get chunky. file size stays cute 💅subs_sidx(sint, default:-1) — how many subsegments per sidx:0: single sidx>0: hierarchical or daisy-chained sidx<0: disables sidx-2: removes sidx if it's already present in the source PID
m4cc(str) — 4 character code of an empty box to append at the end of a segment (DASH mode) or of a fragment (non-DASH mode).chain_sidx(bool, default:false) — daisy-chain those SIDX boxes 🌼msn(uint, default:1) — sequence number of the first moof up to N.msninc(uint, default:1) — how much the sequence number bumps up betweenmoofboxes.tfdt(lfrac, default:0) — set the initial decode time (tfdt) of the first traf.tfdt_traf(bool, default:false) — force atfdtbox into every traf. yes, all of them.nofragdef(bool, default:false) — disable the default fragment flags in the initial moov.straf(bool, default:false) — one single traf per moof (smooth streaming and friends).strun(bool, default:false) — one single trun per traf (smooth streaming and friends again).prft(enum, default:sender) — set the prft box mode, disabled if you're not in fragmented mode:off: no prft box, byesender: put ntp time before the encoderboth: put sender time (if it exists) and ntp time when writing the moof
psshs(enum, default:moov) — where pssh boxes get stored:moof: in the first moof of each segmentmoov: in the movie boxboth: in the movie box and in the first moof of each segmentnone: pssh is discarded, gone, deleted 🗑️
sgpd_traf(bool, default:false) — store sample group descriptions in traf (duplicated for each traf). skip it and they go in the movie box instead.vodcache(enum, default:replace) — enable temp storage for VoD dash modes:on: temp-stores the complete file for sidx and ssix injectioninsert: inserts sidx and ssix by shifting bytes in the output filereplace: precomputes pace requirements for sidx and ssix and rewrites the file range at the end
noinit(bool, default:false) — don't produce an initial moov. used for DASH bitstream switching mode.tktpl(enum, default:yes) — use the track box from input, if there is one, as a template to create a new track:no: disables templateyes: clones the track (except edits and decoder config)udta: only loads udta
mudta(enum, default:yes) — use udta and other moov extension boxes from input, if any:no: disables importyes: clones all extension boxesudta: only loads udta
mvex(bool, default:false) — set mvex boxes after trak boxes.sdtp_traf(enum, default:no) — use an sdtp box in the traf box instead of using flags in trun sample entries:no: do not use sdtpsdtp: use sdtp box to indicate sample dependencies and don't write info in trun sample flagsboth: use sdtp box to indicate sample dependencies and write info in trun sample flags
trackid(uint, default:0) — track ID of the created track for single track. default0uses the next available trackID.fragdur(bool, default:false) — fragment based on fragment duration instead of CTS. mostly used for the MP4Box-fragoption.btrt(bool, default:true) — set btrt box in sample description.styp(str) — set the segment styp major brand (and optionally version) to the given 4CC[.version].lmsg(bool, default:false) — set lmsg brand for the last segment or fragment.mediats(sint, default:0) — set media timescale.0means inherit from PID,-1means derive from samplerate or frame rate.ase(enum, default:v0) — set audio sample entry mode for more than stereo layouts:v0: use v0 signaling but channel count from stream, recommended for backward compatibilityv0s: use v0 signaling and force channel count to 2 (stereo) if more than 2 channelsv1: use v1 signaling, ISOBMFF style (will mux raw PCM as ISOBMFF style)v1qt: use v1 signaling, QTFF stylev2qt: use v2 signaling, QTFF style (lpcm entry type)
ssix(bool, default:false) — create an ssix box when sidx box is present, level 1 mapping I-frames byte ranges, level0xFFmapping the rest.ccst(bool, default:false) — insert coding constraint box for video tracks.maxchunk(uint, default:0) — set max chunk size in bytes for runs (only used in non-fragmented mode).0means no constraints.noroll(bool, default:false) — disable roll sample grouping.norap(bool, default:false) — disable rap sample grouping.saio32(bool, default:false) — use 32 bit offset for side data location instead of 64 bit offset.tfdt64(bool, default:false) — use 64 bit tfdt and sidx even for 32 bit timestamps.compress(enum, default:no) — set top-level box compression mode:no: disable box compressionmoov: compress only moov box (uses cmov for QT)moof: compress only moof boxessidx: compress moof and sidx boxesssix: compress moof, sidx and ssix boxesall: compress moov, moof, sidx and ssix boxes
fcomp(bool, default:false) — force using compress box even when the compressed size is larger than uncompressed. yeah. even then.otyp(bool, default:false) — inject original file type when using compressed boxes.trun_inter(bool, default:false) — interleave samples in trun based on the temporal level, lowest level stored first (this will create as many trun boxes as required 👀).truns_first(bool, default:false) — store track runs before sample group description and sample encryption information.block_size(uint, default:10000) — target output block size,0for the default internal value (10k).boxpatch(str) — apply box patch before writing.deps(bool, default:true) — add samples dependencies information.mfra(bool, default:false) — enable movie fragment random access when fragmenting (ignored when dashing).forcesync(bool, default:false) — force all SAP types to be considered sync samples (might produce non-compliant files ⚠️).refrag(bool, default:false) — use track fragment defaults from the initial file if any rather than computing them from PID properties (used when processing standalone segments/fragments).itags(enum, default:strict) — tag injection mode:none: do not inject tagsstrict: only inject recognized itunes tagsall: inject all possible tags
keep_utc(bool, default:false) — force all new files and tracks to keep the source UTC creation and modification times.pps_inband(bool, default:no) — when.I xps_inbandis set, inject PPS in each non SAP 1/2/3 sample.moovpad(uint, default:0) — insert a free box of given size after moov for future in-place editing.cmaf(enum, default:no) — use CMAF guidelines (turns onmvex,truns_first,strun,straf,tfdt_traf,chain_sidxand restrictssubs_sidxto-1or0):no: CMAF not enforcedcmfc: use CMAF cmfc guidelinescmf2: use CMAF cmf2 guidelines (turns onnofragdef)
pad_sparse(bool, default:true) — inject sample with no data (size 0) to keep durations in unknown sparse text and metadata tracks.force_dv(bool, default:false) — force DV sample entry types even when AVC/HEVC compatibility is signaled.dvsingle(bool, default:false) — ignore DolbyVision profile 8 in xps inband mode if profile 5 is already set.tsalign(bool, default:true) — enable timeline realignment to 0 for the first sample. iffalse, this keeps original timing with an empty edit (possibly long) at the beginning.chapm(enum, default:both) — chapter storage mode:off: disable chapterstk: use chapter track (QT-style)udta: use user-data box chaptersboth: use both chapter tracks and udta
patch_dts(bool, default:false) — patch previous samples duration when dts do not increase monotonically.uncv(enum, default:prof) — use uncv (ISO 23001-17) for raw video:off: disabled (always the case when muxing to QT)gen: enabled, do not write profileprof: enabled and write profile if knowntiny: enabled and write reduced version if profile known and compatible
trunv1(bool, default:false) — force using version 1 of trun regardless of media type or CMAF brand.rsot(bool, default:false) — inject redundant sample timing information when present.
🎀 rfqcp 🎀
Description: QCP reframer
This filter parses QCP files/data and outputs the corresponding audio PID and frames. it's giving ✨audio✨ bestie
Options (expert):
index(dbl, default:1.0) — indexing window length.
🦋 rfh263 🦋
Description: H263 reframer
This filter parses H263 files/data and outputs the corresponding visual PID and frames. moving pictures fr fr 📸
Options (expert):
fps(frac, default:15000/1000) — import frame rate.index(dbl, default:1.0) — indexing window length.notime(bool, default:false) — ignore input timestamps, rebuild from 0.
💅 rfmpgvid 💅
Description: M1V/M2V/M4V reframer
This filter parses MPEG-1/2 and MPEG-4 part 2 video files/data and outputs the corresponding video PID and frames.
Note: The filter uses negative CTS offsets: CTS is correct, but some frames may have DTS greater than CTS. that's just how it is bestie 😭
Options (expert):
fps(frac, default:0/1000) — import frame rate (0defaults to FPS from bitstream or 25 Hz).index(dbl, default:-1.0) — indexing window length. If0, bitstream is not probed for duration. A negative value skips the indexing if the source file is larger than 20M (slows down importers) unless a play with start range> 0is issued.vfr(bool, default:false) — set variable frame rate import.importer(bool, default:false) — compatibility with old importer, displays import results.notime(bool, default:false) — ignore input timestamps, rebuild from 0.
🌸 nhntr 🌸
Description: NHNT reader
This filter reads NHNT files/data to produce a media PID and frames. NHNT documentation is available at https://wiki.gpac.io/xmlformats/NHNT-Format 📚
Options (expert):
reframe(bool, default:false) — force re-parsing of referenced content.index(dbl, default:1.0) — indexing window length.
💜 nhmlr 💜
Description: NHML reader
This filter reads NHML files/data to produce a media PID and frames. NHML documentation is available at https://wiki.gpac.io/xmlformats/NHML-Format 📖
Options (expert):
reframe(bool, default:false) — force re-parsing of referenced content.index(dbl, default:1.0) — indexing window length.
🎬 rfnalu
Description: AVC/HEVC reframer
Bestie, this filter takes your AVC|H264 and HEVC files/data, parses them, and spits out the corresponding video PID and frames. 💖
The output is ISOBMFF-compatible, which means: start codes get yeeted, a NALU length field gets added, and the avcC/hvcC config gets built. Slay.
⚠️ Heads up: the filter uses negative CTS offsets. CTS is correct, but some frames may have DTS greater than CTS. That's just how it is, no cap.
✨ Options (expert) ✨
fps(frac, default:0/1000) — import frame rate.0defaults to the FPS from the bitstream, or25Hz.index(dbl, default:-1.0) — indexing window length. If0, the bitstream is not probed for duration. A negative value skips the indexing if the source file is larger than 20M (which slows down importers) unless a play with start range > 0 is issued.explicit(bool, default:false) — use explicit layered (SVC/LHVC) import.force_sync(bool, default:false) — force sync points on non-IDR samples with I slices. > Not compliant, iykyk. 🙈strict_poc(enum, default:off) — delay frame output of an entire GOP to ensure CTS info is correct when POC suddenly changes.off: disable GOP bufferingon: enable GOP buffering, assuming no error in POCerror: enable GOP buffering and try to detect lost frames
nosei(bool, default:false) — remove all sei messages.nosvc(bool, default:false) — remove all SVC/MVC/LHVC data.novpsext(bool, default:false) — remove all VPS extensions.importer(bool, default:false) — compatibility with old importer, displays import results.nal_length(uint, default:4) — set number of bytes used to code length field:1,2or4.subsamples(bool, default:false) — import subsamples information.deps(bool, default:false) — import sample dependency information.refs(bool, default:false) — import sample reference picture list (currently only for HEVC and VVC).seirw(bool, default:true) — rewrite AVC sei messages for ISOBMFF constraints.audelim(bool, default:false) — keep Access Unit delimiter in payload.keepfiller(bool, default:false) — keep filler NAL units in output.notime(bool, default:false) — ignore input timestamps, rebuild from 0.dv_mode(enum, default:auto) — signaling for DolbyVision.none: never signal DV profileauto: signal DV profile if RPU or EL are foundclean: do not signal and remove RPU and EL NAL unitssingle: signal DV profile if RPU are found and remove EL NAL units
dv_profile(uint, default:0) — profile for DolbyVision (currently defined profiles are4,5,7,8,9),0for auto-detect.dv_compatid(enum, default:auto) — cross-compatibility ID for DolbyVision.auto: auto-detectnone: no cross-compatibilityhdr10: CTA HDR10, as specified by EBU TR 03bt709: SDR BT.709hlg709: HLG BT.709 gamut in ITU-R BT.2020hlg2100: HLG BT.2100 gamut in ITU-R BT.2020bt2020: SDR BT.2020brd: Ultra HD Blu-ray Disc HDR
bsdbg(enum, default:off) — debug NAL parsing in media@debug logs.off: not enabledon: enabledfull: enable with number of bits dumped
📼 m2psdmx
Description: MPEG PS demultiplexer
This filter demultiplexes MPEG-2 program streams to produce media PIDs and frames. That's literally the whole job. 🫶
No options
🎞️ avidmx
Description: AVI demultiplexer
This filter demultiplexes AVI files to produce media PIDs and frames. Old school but still eating. ✨
✨ Options (expert) ✨
fps(frac, default:1/0) — import frame rate, default is AVI one.importer(bool, default:false) — compatibility with old importer, displays import results.noreframe(bool, default:false) — skip media reframer.
📝 txtin
Description: Subtitle loader
This filter reads subtitle data from input PID to produce subtitle frames on a single PID. 💅
The formats it supports are:
- SRT: https://en.wikipedia.org/wiki/SubRip
- WebVTT: https://www.w3.org/TR/webvtt1/
- TTXT: https://wiki.gpac.io/xmlformats/TTXT-Format-Documentation
- QT 3GPP Text XML (TexML): Apple QT6, likely deprecated
- TTML: https://www.w3.org/TR/ttml2/
- SUB: one subtitle per line formatted as
{start_frame}{end_frame}text - SSA (Substation Alpha): basic parsing support for common files
Input files must be in UTF-8 or UTF-16 format, with or without BOM. The internal frame format is:
- WebVTT (and srt if desired): ISO/IEC 14496-30 VTT cues
- TTML: ISO/IEC 14496-30 XML subtitles
- stxt and sbtt: ISO/IEC 14496-30 text stream and text subtitles
- Others: 3GPP/QT Timed Text
🌸 TTML Support 🌸
If the .I ttml_split option is set, the TTML document is split in independent time segments by inspecting all overlapping subtitles in the body.
Empty periods in TTML will result in empty TTML documents, or will be skipped if the .I no_empty option is set.
The first sample has a CTS assigned as indicated by .I ttml_cts:
- a numerator of
-2indicates the first CTS is0 - a numerator of
-1indicates the first CTS is the first active time in document - a numerator >=
0indicates the CTS to use for first sample
When TTML splitting is disabled, the duration of the TTML sample is given by .I ttml_dur if not 0, or set to the document duration.
By default, media resources are kept as declared in TTML2 documents.
ttml_embed can be used to embed inside the TTML sample the resources in <head> or <body>:
- for
<source>,<image>,<audio>,<font>, local URIs indicated insrcwill be loaded andsrcrewritten. - for
<data>with base64 coding, the data will be decoded,<data>element removed and parent<source>rewritten withsrcattribute inserted.
The embedded data is added as a subsample to the TTML frame, and the referring elements will use src=urn:mpeg:14496-30:N with N the index of the subsample.
A subtitle zero may be specified using .I ttml_zero. This will remove all subtitles before the given time T0, and rewrite each subtitle begin/end T to T-T0 using millisecond accuracy.
⚠️ Warning: Original time formatting (tick, frames/subframe ...) will be lost when this option is used, converted to HH:MM:SS.ms. 😭
The subtitle zero time must be prefixed with T when the option is not set as a global argument:
gpac -i test.ttml:ttml_zero=T10:00:00 [...]
MP4Box -add test.ttml:sopt:ttml_zero=T10:00:00 [...]
gpac -i test.ttml --ttml_zero=10:00:00 [...]
gpac -i test.ttml --ttml_zero=T10:00:00 [...]
MP4Box -add test.ttml --ttml_zero=10:00:00 [...]
🌈 Simple Text Support 🌈
The text loader can convert input files in simple text streams of a single packet, by forcing the codec type on the input:
gpac -i test.txt:#CodecID=stxt [...]
gpac fin:pck="Text Data":#CodecID=stxt [...]
The content of the source file will be the payload of the text sample.
The .I stxtmod option allows specifying WebVTT, TX3G or simple text mode for output format.
In this mode, the .I stxtdur option is used to control the duration of the generated subtitle:
- a positive value always forces the duration
- a negative value forces the duration if input packet duration is not known
💭 Notes 💭
When reframing simple text streams from demuxers (e.g. subtitles from MKV), the output format of these streams can be selected using .I stxtmod.
When importing SRT, SUB or SSA files, the output format of the PID can be selected using .I stxtmod.
✨ Options (expert) ✨
nodefbox(bool, default:false) — skip default text box.noflush(bool, default:false) — skip final sample flush for srt.fontname(str) — default font.fontsize(uint, default:18) — default font size.lang(str) — default language.width(uint, default:0) — default width of text area.height(uint, default:0) — default height of text area.txtx(uint, default:0) — default horizontal offset of text area:-1(left),0(center) or1(right).txty(uint, default:0) — default vertical offset of text area:-1(bottom),0(center) or1(top).zorder(sint, default:0) — default z-order of the PID.timescale(uint, default:1000) — default timescale of the PID.ttml_split(bool, default:true) — split ttml doc in non-overlapping samples.ttml_cts(lfrac, default:-1/1) — first sample cts - see filter help.ttml_dur(frac, default:0/1) — sample duration when not spliting split - see filter help.ttml_embed(bool, default:false) — force embedding TTML resources.ttml_zero(str) — set subtitle zero time for TTML.no_empty(bool, default:false) — do not send empty samples.stxtdur(frac, default:1) — duration for simple text.stxtmod(enum, default:tx3g) — text stream mode for simple text streams and SRT inputs.stxt: output PID formatted as simple text stream (remove markup in VTT/SRT payload)sbtt: output PID formatted as subtitle text stream (keep markup in VTT/SRT payload)tx3g: output PID formatted as TX3G/Apple streamvtt: output PID formatted as WebVTT streamwebvtt: same as vtt (for backward compatiblity
🎀 ttxtdec
Description: TTXT/TX3G decoder
This filter decodes TTXT/TX3G streams into a BIFS scene graph of the compositor filter. The TTXT documentation lives at https://wiki.gpac.io/xmlformats/TTXT-Format-Documentation 📖
In stand-alone rendering (no associated video), the filter will use:
- Width and Height properties of input pid if any
- otherwise,
osizeoption of compositor if set - otherwise,
.I txtwand.I txth
✨ Options (expert) ✨
texture(bool, default:false) — use texturing for output text.outline(bool, default:false) — draw text outline.txtw(uint, default:400) — default width in standalone rendering.txth(uint, default:200) — default height in standalone rendering.
🦋 vttdec
Description: WebVTT decoder
This filter decodes WebVTT streams into a SVG scene graph of the compositor filter. ✨
The scene graph creation is done through JavaScript. The filter options are used to override the JS global variables of the WebVTT renderer.
In stand-alone rendering (no associated video), the filter will use:
- Width and Height properties of input pid if any
- otherwise,
osizeoption of compositor if set - otherwise,
.I txtwand.I txth
✨ Options (expert) ✨
script(str, default:$GSHARE/scripts/webvtt-renderer.js) — location of WebVTT SVG JS renderer.font(str, default:SANS, updatable) — font.fontSize(flt, default:20, updatable) — font size.color(str, default:white, updatable) — text color.lineSpacing(flt, default:1.0, updatable) — line spacing as scaling factor to font size.txtw(uint, default:400) — default width in standalone rendering.txth(uint, default:200) — default height in standalone rendering.
✨ ttmldec ✨
Description: TTML decoder — the girl who turns your subtitles into art 💅
Okay so this filter decodes TTML streams into an SVG scene graph of the compositor filter. Cute, right? And the way it builds that scene graph? Through JavaScript ✨. The filter options are literally here to override the JS global variables of the TTML renderer, so you can boss it around however you want.
When it's doing stand-alone rendering (aka no associated video, just vibing solo), the filter will use, in this order:
- the Width and Height properties of the input pid, if there are any
- otherwise, the
osizeoption ofcompositor, if it's set - otherwise,
txtwandtxth
Options (expert):
script(str, default:$GSHARE/scripts/ttml-renderer.js) — where the TTML SVG JS renderer lives 🗺️font(str, default:SANS, updatable) — the font, bestiefontSize(flt, default:20, updatable) — font sizecolor(str, default:white, updatable) — text colorvalign(enum, default:bottom, updatable) — vertical alignmentbottom: align text at bottom of text areacenter: align text at center of text areatop: align text at top of text area
lineSpacing(flt, default:1.0, updatable) — line spacing, expressed as a scaling factor to font sizetxtw(uint, default:400) — default width in standalone renderingtxth(uint, default:200) — default height in standalone rendering
🌸 rtpin 🌸
Description: RTP/RTSP/SDP input — the stream girlie 🎀
This filter handles SDP/RTSP/RTP input reading. It supports:
- SDP file reading
- RTP direct url through
rtp://protocol scheme - RTSP session processing through
rtsp://andsatip://protocol schemes
The filter produces either PIDs with media frames, or file PIDs with multiplexed data (e.g. MPEG-2 TS). Iconic behavior, honestly.
The filter will use:
- RTSP over HTTP tunnel if the server port is
80or8080or if the protocol scheme isrtsph://. - RTSP over TLS if the server port is
322or if the protocol scheme isrtsps://. - RTSP over HTTPS tunnel if the server port is
443and if the protocol scheme isrtsph://.
And bestie, listen: the filter will attempt reconnecting in TLS mode after two consecutive initial connection failures. She's persistent, okay?!
Options (expert):
src(cstr) — location of source content (SDP, RTP or RTSP URL)firstport(uint, default:0) — default first port number to use (0lets the filter decide, she's got this)ifce(str) — default interface IP to use for multicast. IfNULL, the default system interface will be usedttl(uint, default:127, minmax:0-127) — multicast TTLreorder_len(uint, default:1000) — reorder length in packetsreorder_delay(uint, default:50) — max delay in RTP re-orderer; packets will be dispatched after thatblock_size(uint, default:0x100000) — buffer size for RTP/UDP or RTSP when interleaveddisable_rtcp(bool, default:false) — disable RTCP reportingnat_keepalive(uint, default:0) — delay in ms of NAT keepalive, disabled by default (except for SatIP, set to 30s by default)force_mcast(str) — force multicast on indicated IP in RTSP setupuse_client_ports(bool, default:false) — force using client ports (hack for some RTSP servers overriding client ports)bandwidth(uint, default:0) — set bandwidth param for RTSP requestsdefault_port(uint, default:554, minmax:0-65535) — set default RTSP portsatip_port(uint, default:1400, minmax:0-65535) — set default port for SATIPtransport(enum, default:auto) — set RTP over RTSPauto: set interleave on if HTTP tunnel is used, off otherwise and retry in interleaved mode if UDP timeouttcp: enable RTP over RTSPudp: disable RTP over RTSP
udp_timeout(uint, default:10000) — default timeout before considering UDP is downrtcp_timeout(uint, default:5000) — default timeout for RTCP traffic in ms. After this timeout, playback will start out of sync. If0always wait for RTCPfirst_packet_drop(uint, default:0, updatable) — set number of first RTP packet to drop (0if no drop)frequency_drop(uint, default:0, updatable) — drop 1 out of N packet (0disable dropping)loss_rate(sint, default:-1, updatable) — loss rate to signal in RTCP,-1means real loss rate, otherwise a per-thousand of packet lostuser_agent(str, default:$GUA) — user agent string, by default solved from GPAC preferenceslanguages(str, default:$GLANG) — user languages, by default solved from GPAC preferencesstats(uint, default:500) — update statistics to the user every given MS (0disables reporting)max_sleep(sint, default:1000) — set max sleep in milliseconds:- a negative value
-Nmeans to always sleep forNms - a positive value
Nmeans to sleep at mostNms but will sleep less if frame duration is shorter
- a negative value
rtcpsync(bool, default:true) — use RTCP to adjust synchronizationforceagg(bool, default:false) — force RTSP control aggregation (patch for buggy servers)ssm(strl) — list of IP to include for source-specific multicastssmx(strl) — list of IP to exclude for source-specific multicast
💾 fout 💾
Description: File output — she writes things to disk and that's it, no notes 💅
This filter is used to write data to disk, and does not produce any output PID. Periodt.
In regular mode, the filter only accepts PID of type file. It will dump to file incoming packets (stream type file), starting a new file for each packet having a frame_start flag set, unless operating in cat mode.
If the output file name is std or stdout, writes to stdout. Slay.
The output file name can use gpac templating mechanism, see gpac -h doc. The filter watches the property FileNumber on incoming packets to create new files.
By default output files are created directly, which may lead to issues if concurrent programs attempt to access them. 🫠
By enabling atomic, files will be created in target destination folder with the .gftmp suffix and move to their final name upon close. Clean girl behavior ✨.
🗑️ Discard sink mode 🗑️
When the destination is null, the filter is a sink dropping all input packets. In this case it accepts ANY type of input PID, not just file ones. She's flexible like that.
🌈 HTTP streaming recording 🌈
When recording a DASH or HLS session, the number of segments to keep per quality can be set using max_cache_segs.
- value
0keeps everything (default behaviour) - a negative value
Nwill keep-Nfiles regardless of the time-shift buffer value - a positive value
Nwill keepMAX(N, time-shift buffer)files
Example
gpac -i LIVE_MPD dashin:forward=file -o rec/$File$:max_cache_segs=3
This will force keeping a maximum of 3 media segments while recording the DASH session. Obsessed with the efficiency honestly 🔥.
Options (expert):
dst(cstr) — location of destination fileappend(bool, default:false) — open in append modedynext(bool, default:false) — indicate the file extension is set by filter chain, notdststart(dbl, default:0.0) — set playback start offset. A negative value means percent of media duration with-1equal to durationspeed(dbl, default:1.0) — set playback speed when vsync is on. If negative andstartis0,startis set to-1ext(cstr) — set extension for graph resolution, regardless of file extensionmime(cstr) — set mime type for graph resolutioncat(enum, default:none) — cat each file of input PID rather than creating one file per filenamenone: never cat filesauto: only cat if files have same namesall: always cat regardless of file names
ow(enum, default:yes) — overwrite output mode when concatenation is not usedyes: override file if existingno: throw error if file existingask: interactive prompt
mvbk(uint, default:8192) — block size used when moving parts of the file around in patch moderedund(bool, default:false) — keep redundant packet in output filemax_cache_segs(sint, default:0) — maximum number of segments cached per HAS quality when recording live sessions (0means no limit)force_null(bool, default:false) — force no output regardless of file nameatomic(bool, default:false) — use atomic file write for non append modes
🧚 uflatm 🧚
Description: LATM rewriter
This filter converts AAC streams into LATM encapsulated data. Glow up for your audio ✨.
Options (expert):
fdsi(frac, default:0) — set delay between two LATM Audio Config
🍓 ufadts 🍓
Description: ADTS rewriter
This filter converts AAC streams into ADTS encapsulated data. Different wrapper, same queen 💅.
Options (expert):
mpeg2(enum, default:auto) — signal as MPEG2 AACauto: selects based on AAC profileno: always signals as MPEG-4 AACyes: always signals as MPEG-2 AAC
👑 ufmhas 👑
Description: MHAS rewriter
This filter converts MPEG-H Audio streams into MHAS encapsulated data. Fancy audio, fancy wrapper, no cap.
Options (expert):
syncp(bool, default:false) — if set, insert sync packet at each frame, otherwise only at SAP
🔥 reframer 🔥
Description: Media reframer — the multitasking main character 💖
This filter provides various tools on inputs:
- ensure reframing (1 packet = 1 Access Unit)
- optionally force decoding
- real-time regulation
- packet filtering based on SAP types or frame numbers
- time-range extraction and splitting
This filter forces input PIDs to be properly framed (1 packet = 1 Access Unit).
It is typically needed to force remultiplexing in file to file operations when source and destination files use the same format. iykyk.
🔍 SAP filtering 🔍
The filter can remove packets based on their SAP types using the saps option.
For example, this can be used to extract only the key frame (SAP 1,2,3) of a video to create a trick mode version. Trick mode queen 💅.
🎞️ Frame filtering 🎞️
This filter can keep only specific Access Units of the source using the frames option.
For example, this can be used to extract only specific key pictures of a video to create a HEIF collection. So cute, so curated 🎀.
🪄 Frame decoding 🪄
This filter can force input media streams to be decoded using the raw option.
Example
gpac -i m.mp4 reframer:raw=av [dst]
⏰ Real-time Regulation ⏰
The filter can perform real-time regulation of input packets, based on their timescale and timestamps.
For example to simulate a live DASH:
gpac -i m.mp4 reframer:rt=on -o live.mpd:dynamic
Range extraction
The filter can do time range extraction on the source, using the xs and xe options. Yes bestie, it just yoinks the bits you want and leaves the rest. ✂️
The formats allowed for time specifiers are:
'TC'HH:MM:SS:FF— specify time in timecode'T'H:M:S,'T'M:S— specify time in hours, minutes, seconds'T'H:M:S.MS,'T'M:S.MS,'T'S.MS— specify time in hours, minutes, seconds and millisecondsINT,FLOAT,NUM/DEN— specify time in seconds (number or fraction)'D'INT,'D'FLOAT,'D'NUM/DEN— specify end time as offset to start time in seconds (number or fraction) — only valid forxe'F'NUM— specify time as frame number, 1 being first- XML DateTime — specify absolute UTC time
In this mode, the timestamps get rewritten to form a continuous timeline, unless xots is set. Unless you say otherwise, time starts fresh at zero.
When multiple ranges are given, the filter will try to seek if needed and supported by source.
Example
gpac -i m.mp4 reframer:xs=T00:00:10,T00:01:10,T00:02:00:xe=T00:00:20,T00:01:20 [dst]
This will extract the time ranges [10s,20s], [1m10s,1m20s] and all media starting from 2m. 🎀
If no end range is found for a given start range:
- if a following start range is set, the end range is set to this next start
- otherwise, the end range is open
Example
gpac -i m.mp4 reframer:xs=0,10,25:xe=5,20 [dst]
This will extract the time ranges [0s,5s], [10s,20s] and all media starting from 25s.
Example
gpac -i m.mp4 reframer:xs=0,10,25 [dst]
This will extract the time ranges [0s,10s], [10s,25s] and all media starting from 25s.
It is possible to signal range boundaries in output packets using splitrange. This will expose on the first packet of each range in each PID the following properties:
FileNumber— starting at 1 for the first range, to be used as replacement for$num$in templatesFileSuffix— corresponding toStartRange_EndRangeorStartRangefor open ranges, to be used as replacement for$FS$in templates
Example
gpac -i m.mp4 reframer:xs=T00:00:10,T00:01:10:xe=T00:00:20:splitrange -o dump_$FS$.264 [dst]
This will create two output files dump_T00.00.10_T00.02.00.264 and dump_T00.01.10.264.
Note: The:and/characters are replaced by.inFileSuffixproperty. 💅
It is possible to modify PID properties per range using props. Each set of property must be specified using the active separator set.
Warning: The option must be escaped using double separators in order to be parsed properly. Do not skip the extra separators, bestie, the parser will simply not get it.
Example
gpac -i m.mp4 reframer:xs=0,30::props=#Period=P1,#Period=P2:#foo=bar [dst]
This will assign to output PIDs:
- during the range
[0,30]: propertyPeriodtoP1 - during the range
[30, end]: propertiesPeriodtoP2and propertyfootobar
For uncompressed audio PIDs, input frame will be split to closest audio sample number.
When xround is set to seek, the following applies:
- a single range shall be specified
- the first I-frame preceding or matching the range start is used as split point
- all packets before range start are marked as seek points
- packets overlapping range start are forwarded with a
SkipBeginproperty set to the amount of media to skip - packets overlapping range end are forwarded with an adjusted duration to match the range end
This mode is typically used to extract a range in a frame/sample accurate way, rather than a GOP-aligned way. 🎯
When xround is not set to seek, compressed audio streams will still use seek mode. Consequently, these streams will have modified edit lists in ISOBMFF which might not be properly handled by players. This can be avoided using no_audio_seek, but this will introduce audio delay.
Heads up: pick your poison — wonky edit lists or an audio delay. That's the tradeoff, no cap.
UTC-based range extraction
The filter can perform range extraction based on UTC time rather than media time. In this mode, the end time must be:
- a UTC date — range extraction will stop after this date
- a time in second — range extraction will stop after the specified duration
The UTC reference is specified using utc_ref. If UTC signal from media source is used, the filter will probe for utc_probe before considering the source has no UTC signal.
The properties SenderNTP and, if absent, UTC of source packets are checked for establishing the UTC reference. 🕰️✨
Other split actions
The filter can perform splitting of the source using xs option. The additional formats allowed for xs option are:
SAP— split source at each SAP/RAP'D'VAL— split source by chunks ofVALseconds'D'NUM/DEN— split source by chunks ofNUM/DENseconds'S'VAL— split source by chunks of estimated sizeVALbytes (can use property multipliers, e.g.m)
Note: In these modes,splitrangeandxadjustare implicitly set. Sneaky auto-config, love that for us.
Absorbing stream discontinuities
Discontinuities may happen quite often in streaming sessions due to resolution switching, codec change, etc ...
While GPAC handles these discontinuities internally, it may be desired to ignore them, for example when a source is known to have no discontinuity but GPAC detects some due to network errors or other changing properties that should be ignored.
The nodisc option allows removing all discontinuities once a stream is setup.
Warning: Make sure you know what you are doing as using this option could make the stream not playable (ignoring a codec config change). Fr fr, this one can absolutely break your playback. Do not vibe-code your way through it. 💀
Example
gpac -i SOMEURL reframer:nodisc -o DASH_ORIGIN
In this example, the dasher filter will never trigger a period switch due to input stream discontinuity.
Options (expert):
exporter(bool, default:false) — compatibility with old exporter, displays export resultsrt(enum, default:off, updatable) — real-time regulation mode of inputoff: disable real-time regulationon: enable real-time regulation, one clock per PIDsync: enable real-time regulation, one clock for all PIDsalign: send packets in DTS order following one clock for all PIDs (undo input packet bursts), no real-time regulation
saps(uintl, Enum:0|1|2|3|4, updatable) — list of SAP types (0,1,2,3,4) to forward, other packets are dropped (forwarding only sap0will break the decoding)refs(bool, default:false, updatable) — forward only frames used as reference frames, if indicated in the input streamspeed(dbl, default:0.0, updatable) — speed for real-time regulation mode, a value of0uses speed from play commandsraw(enum, default:no) — force input AV streams to be in raw formatno: do not force decoding of inputsav: force decoding of audio and video inputsa: force decoding of audio inputsv: force decoding of video inputs
frames(sintl, updatable) — drop all except listed frames (first being1). A negative value-Vkeeps only first frame everyVframesxs(strl) — extraction start time(s). If not set and an extraction end time is set,0is usedxe(strl) — extraction end time(s). If less values than start times, the last time interval extracted is an open rangexround(enum, default:before) — adjust start time of extraction range to I-framebefore: use first I-frame preceding or matching range startseek: see filter helpafter: use first I-frame (if any) following or matching range startclosest: use I-frame closest to range start
xadjust(bool, default:false) — adjust end time of extraction range to be before next I-framexots(bool, default:false) — keep original timestamps after extractionxdts(bool, default:false) — compute start times based on DTS and not CTSnosap(bool, default:false) — do not cut at SAP when extracting range (may result in broken streams)splitrange(bool, default:false) — signal file boundary at each extraction first packet for template-base file generationseeksafe(dbl, default:10.0) — rewind play requests by given seconds (to make sure the I-frame preceding start is catched)tcmdrw(bool, default:true) — rewrite TCMD samples when splittingprops(strl) — extra output PID properties per extraction rangeno_audio_seek(bool, default:false) — disable seek mode on audio streams (no change of priming duration)probe_ref(bool, default:false) — allow extracted range to be longer in case of B-frames with reference frames presented outside of rangeutc_ref(enum, default:any) — set reference mode for UTC range extractionlocal: use UTC of local hostany: use UTC of media, or UTC of local host if not found in media after probing timemedia: use UTC of media (abort if none found)tc: use timecode of media (be careful: considered day will be today)
utc_probe(uint, default:5000) — timeout in milliseconds to try to acquire UTC reference from mediacopy(bool, default:false, updatable) — try copying frame interface into packetscues(enum, default:no, updatable) — cue filtering modeno: do no filter frames based on cue infosegs: only forward frames marked as segment startfrags: only forward frames marked as fragment start
sapcue(uint, default:0) — treat SAPs smaller than or equal to this value as cue pointsrmseek(bool, default:false, updatable) — remove seek flag of all sent packetsnodisc(bool, default:false, updatable) — ignore all discontinuities from input - see filter help
writegen
Description: Stream to File converter 🎀
Generic single stream to file converter, used when extracting/converting PIDs.
The writegen filter should usually not be explicitly loaded without a source ID specified, since the filter would likely match any PID connection.
Lowkey important: don't just yeet writegen in there alone. Without a source ID it'll happily grab basically any PID connection, and that's giving chaos energy. 🌸
okay so these are the expert-level knobs and there are a ton of them, so strap in bestie 💖
exporter(bool, default:false) — compat mode for the old exporter; it displays export results 💅pfmt(pfmt, default:none, Enum:none|yuv420|yvu420|yuv420_10|yuv422|yuv422_10|yuv444|yuv444_10|uyvy|vyuy|yuyv|yvyu|uyvl|vyul|yuyl|yvyl|nv12|nv21|nv1l|nv2l|yuva|yuvd|yuv444a|yuv444p|v308|yuv444ap|v408|v410|v210|grey|algr|gral|rgb8|rgb4|rgb5|rgb6|rgba|argb|bgra|abgr|rgb|bgr|xrgb|rgbx|xbgr|bgrx|rgbd|rgbds|uncv) — pixel format for raw extract. If you don't set it, it gets derived from the extension ✨afmt(afmt, default:none, Enum:none|u8|s16|s16b|s24|s24b|s32|s32b|flt|fltb|dbl|dblb|u8p|s16p|s24p|s32p|fltp|dblp) — audio format for raw extract. Not set? Derived from the extension, same deal 🎀decinfo(enum, default:auto) — decoder config insert mode, i.e. when do we shove that config in:no: never inserted, it's giving mystery 🙈first: inserted on the first packetsap: inserted at each SAPauto: picks betweennoandfirstdepending on the media type
split(bool, default:false) — force one file per frame 🍓frame(bool, default:false) — force a single frame dump with no rewrite. In this mode, all codec types are supported 👑sstart(uint, default:0) — start number of frame to forward. If0, all samples are forwardedsend(uint, default:0) — end number of frame to forward. If it's less than the start frame, all samples after start are forwardeddur(frac, default:0) — duration of media to forward after the first sample. If0, all samples are forwardedmerge_region(bool, default:false) — merge TTML regions with the same ID while reassembling the TTML doc 🦋vtth(enum, default:seg) — vtt header injection mode:single: inject only at the first frame of the streamseg: inject at each non-empty segmentall: inject at each segment even the empty ones
add_nl(bool, default:false) — add a new line after each packet when dumping text streamsrawb(bool, default:false) — force direct dump of input without framing rewrite. In this mode, all codec types are supported 💜
✨ ufnalu ✨
Description: AVC/HEVC to AnnexB rewriter
This filter converts AVC|H264 and HEVC streams into AnnexB format, with inband parameter sets and start codes. it's literally just doing the format glow-up 🔥
🎀 Options (expert) 🎀
rcfg(bool, default:true) — force repeating decoder config at each I-frameextract(enum, default:all) — layer extraction mode:all: extracts all layers 🌈base: extract base layer onlylayer: extract non-base layer(s) only
delim(bool, default:true) — insert AU Delimiter NALpps_inband(bool, default:false) — inject PPS at each non SAP frame. Ignored ifrcfgis not set, so don't even try it 💀
🦋 writeqcp 🦋
Description: QCP writer
This filter converts a single QCELP, EVRC or MSV stream to a QCP output file.
🎀 Options (expert) 🎀
exporter(bool, default:false) — compat mode for the old exporter; displays export results 💅
🌸 ufvtt 🌸
Description: WebVTT rewriter
This filter converts a single ISOBMFF WebVTT stream to its unframed format. undoing the framing, main character energy 😌
🎀 Options (expert) 🎀
exporter(bool, default:false) — compat mode for the old exporter; displays export results 💅merge_cues(bool, default:true) — merge VTT cues (undo the ISOBMFF cue split)noempty(bool, default:false) — do not create an empty file if no VTT cues are present
⭐ nhntw ⭐
Description: NHNT writer
This filter converts a single stream to an NHNT output file. NHNT documentation is available at https://wiki.gpac.io/xmlformats/NHNT-Format — go read it bestie, iykyk 📚
🎀 Options (expert) 🎀
exporter(bool, default:false) — compat mode for the old exporter; displays export results 💅large(bool, default:false) — use large file mode
🧚 nhmlw 🧚
Description: NHML writer
This filter converts a single stream to an NHML output file. NHML documentation is available at https://wiki.gpac.io/xmlformats/NHML-Format ✨
🎀 Options (expert) 🎀
exporter(bool, default:false) — compat mode for the old exporter; displays export results 💅dims(bool, default:false) — use DIMS modename(str) — set the output name of the media and info files producednhmlonly(bool, default:false) — only dump NHML info, not the mediapckp(bool, default:false) — full NHML dumppayload(bool, default:false) — dump payload (scte35only at the moment), should be combined withǹhmlonlychksum(enum, default:none) — insert frame checksum:none: no checksum 🙅crc: CRC32 checksumsha1: SHA1 checksum
💜 vobsubdmx 💜
Description: VobSub demultiplexer
This filter parses VobSub files/data to produce media PIDs and frames.
🎀 Options (expert) 🎀
blankframe(bool, default:true) — force inserting a blank frame if the first subpic is not at0keepempty(bool, default:false) — declare VobSub tracks with no frames (yes, empty ones, they exist)
🔥 avimx 🔥
Description: AVI multiplexer
This filter multiplexes raw or compressed audio and video to produce an AVI output.
Unlike other multiplexing filters in GPAC, this filter is a sink filter and does not produce any PID to be redirected in the graph. so don't go looking for a PID to redirect, it's not happening 💀
The filter can however use template names for its output, using the first input PID to resolve the final name.
The filter watches the property FileNumber on incoming packets to create new files. 👀
The filter will look for the property AVIType set on the input stream. The value can either be a 4CC or a string, indicating the mux format for the PID.
If the string is prefixed with + and the decoder configuration is present and formatted as an ISOBMFF box, the box header will be removed.
🎀 Options (expert) 🎀
dst(cstr) — location of the destination filefps(frac, default:25/1) — default framerate if none is indicated in the streamnoraw(bool, default:false) — disable raw output in AVI, only compressed ones allowedopendml_size(luint, default:0) — force opendml format when chunks are larger than this amount (0means 1.9Gb max size in each riff chunk)
🎧 aout 🎧
Description: Audio output
This filter writes a single PCM (uncompressed) audio input PID to a sound card or other audio output device. 🔊
The longer the audio buffering .I bdur is, the longer the audio latency will be (pause/resume). The quality of fast forward audio playback will also be degraded when using large audio buffers. big buffers = big vibes but also big lag, ngl 😭
If .I clock is set, the filter will report system time (in us) and the corresponding packet CTS for other filters to use for AV sync.
🎀 Options (expert) 🎀
drv(cstr) — audio driver namebnum(uint, default:2) — number of audio buffers (0for auto)bdur(uint, default:100) — total duration of all buffers in ms (0for auto)threaded(bool, default:true) — force dedicated thread creation if the sound card driver is not threadeddur(frac, default:0) — only play the specified durationclock(bool, default:true) — hint audio clock for this streamspeed(dbl, default:1.0, updatable) — set playback speed. If speed is negative and start is0, start is set to-1start(dbl, default:0.0, updatable) — set playback start offset. A negative value means percent of media duration, with-1equal to durationvol(uint, default:100, minmax:0-100, updatable) — set default audio volume, as a percentage between0and100pan(uint, default:50, minmax:0-100, updatable) — set stereo pan, as a percentage between0and100,50being centeredbuffer(uint, default:200) — set playout buffer in msmbuffer(uint, default:0) — set max buffer occupancy in ms. If it's less than buffer, use bufferrbuffer(uint, default:0, updatable) — rebuffer trigger in ms. If0or more than buffer, disable rebufferingadelay(frac, default:0, updatable) — set audio delay in secbuffer_done(bool) — buffer done indication (readonly, for user app)rebuffer(luint) — system time in us at which the last rebuffer started,0if not rebuffering (readonly, for user app)media_offset(dbl, default:0) — media offset (substract this value to CTS to get media time — readonly)
🌈 ufm4v 🌈
Description: M4V rewriter
This filter converts MPEG-4 part 2 visual streams into writable format (reinsert decoder config).
🎀 Options (expert) 🎀
rcfg(bool, default:true) — force repeating decoder config at each I-frame
👑 ufvc1 👑
Description: VC1 rewriter
This filter converts VC1 visual streams into writable format (reinsert decoder config and start codes if needed).
🎀 Options (expert) 🎀
rcfg(bool, default:true) — force repeating decoder config at each I-frame
💖 resample 💖
Description: Audio resampler
This filter resamples raw audio to a target sample rate, number of channels or audio format. the audio glow-up filter fr fr 🎶
🎀 Options (expert) 🎀
och(uint, default:0) — desired number of output audio channels (0for auto)osr(uint, default:0) — desired sample rate of output audio (0for auto)osfmt(afmt, default:none) — desired sample format of output audio (nonefor auto)olayout(alay, Enum:mono|stereo|3/0.0|3/1.0|3/2.0|3/2.1|5/2.1|1+1|2/1.0|2/2.0|3/3.1|3/4.1|11/11.2|5/2.1|5/5.2|5/4.1|6/5.1|6/7.1|5/6.1|7/6.1) — desired CICP layout of output audio (nullfor auto)
🫶 vout 🫶
Description: Video output
This filter displays a single visual input PID in a window. 🪟
The window is created unless a window handle (HWND, xWindow, etc) is indicated in the config file ([Temp]OSWnd=ptr).
The output uses the GPAC video output module indicated in the .I drv option or in the config file (see GPAC core help).
The video output module can be further configured (see GPAC core help).
The filter can use OpenGL or 2D blit of the graphics card, depending on the OS support.
The filter can be used to dump frames as written by the graphics card (GPU read-back) using .I dumpframes. 🖼️
In this case, the window is not visible and only the listed frames are drawn to the GPU.
The pixel format of the dumped frame is always RGB in OpenGL and matches the video backbuffer format in 2D mode. ✨
no cap, that was a lot of filters — and there's more coming, so stay tuned bestie 💅
drv(cstr) — video driver name. ur literal chauffeur for pixels 🚗💨vsync(bool, default:true) — turn on video screen sync ✨drop(bool, default:false, updatable) — enable dropping late frames (yes bestie, sometimes we gotta let them go 💀)disp(enum, default:gl) — display mode, pick ur fighter:gl: OpenGLpbo: OpenGL with PBOblit: 2D hardware blitsoft: software blit
start(dbl, default:0.0, updatable) — set playback start offset. a negative value means percent of media duration, and-1is literally equal to duration 👑dur(lfrac, default:0) — only play the specified duration. that's it, that's the whole snack 🍓speed(dbl, default:1.0, updatable) — set playback speed whenvsyncis on. if speed is negative andstartis0, thenstartgets set to-1🔥hold(dbl, default:1.0) — number of seconds to hold display for single-frame streams. a negative value forces a hold on the last frame for single or multi-frame streams, no cap 🫶linear(bool, default:false) — use linear filtering instead of nearest pixel, GL mode onlyback(uint, default:0x808080) — back color for transparent imageswsize(v2di, default:-1x-1) — default init window size:0x0holds the window size of the first frame- negative values indicate video media size
wpos(v2di, default:-1x-1) — default position (0,0is top-left, iykyk)vdelay(frac, default:0, updatable) — set delay in sec. a positive value displays after the audio clock ⏰hide(bool, default:false) — hide output window (sneaky link mode 🙈)fullscreen(bool, default:false, updatable) — use fullscreen, main character energy 👑buffer(uint, default:100) — set playout buffer in msmbuffer(uint, default:0) — set max buffer occupancy in ms. if less thanbuffer, usebufferrbuffer(uint, default:0, updatable) — rebuffer trigger in ms. if0or more thanbuffer, rebuffering is disableddumpframes(uintl) — ordered list of frames to dump,1being the first frame. special value0means dump all the frames 📸out(str, default:dump) — radical of dump frame filenames. if no extension is provided, frames are exported as$OUT_%d.PFMTasync(bool, default:true) — sync video to audio output, if any 🎧owsize(v2di) — output window size (readonly)buffer_done(bool) — buffer done indication (readonly)rebuffer(luint) — system time in us at which the last rebuffer started,0if not rebuffering (readonly)vjs(bool, default:true) — use the default JS script for vout controlmedia_offset(dbl, default:0) — media offset (substract this value to CTS to get media time — readonly)wid(uint, default:0) — window id (readonly)vflip(enum, default:no, updatable) — flip video (GL only, bestie):no: no flippingv: vertical fliph: horizontal flipvh: horizontal and verticalhv: same asvh
vrot(enum, default:0, updatable) — rotate video by the given angle:0: no rotation90: rotate 90 degree counter clockwise180: rotate 180 degree270: rotate 90 degree clockwise
✂️ vcrop ✂️
Description: Video cropper
this filter is used to crop raw video data. it's giving scissors but make it code 💅
🎀 Options (expert):
wnd(str) — size of output to crop, indicated asTxLxWxH. if%is indicated after a number, the value is in percent of the source width (forLandW) or height (forTandH). an absolute offset (+x,-x) can be added after the percent sign 🌸copy(bool, default:false) — copy the source pixels. by default the filter will try to forward crop frames by adjusting offsets and strides of the source, if possible (window contained in frame)round(enum, default:up) — adjust dimension to be a multiple of2:up: up roundingdown: down roundingallup: up rounding on formats that do not require it (RGB, YUV444)alldown: down rounding on formats that do not require it (RGB, YUV444)
🔄 vflip 🔄
Description: Video flipper
this filter flips uncompressed video frames vertically, horizontally, in both directions, or... no flip at all. the range 😭
🎀 Options (expert):
mode(enum, default:vert, updatable) — flip mode:off: no flipping (passthrough)vert: vertical fliphoriz: horizontal flipboth: horizontal and vertical flip
🎥 rfrawvid 🎥
Description: RAW video reframer
this filter parses raw YUV and RGB files/data and outputs the corresponding raw video PID and frames. slay ✨
the filter also parses YUV4MPEG format, periodt.
🎀 Options (expert):
size(v2di, default:0x0) — source video resolutionspfmt(pfmt, default:none, Enum:none|yuv420|yvu420|yuv420_10|yuv422|yuv422_10|yuv444|yuv444_10|uyvy|vyuy|yuyv|yvyu|uyvl|vyul|yuyl|yvyl|nv12|nv21|nv1l|nv2l|yuva|yuvd|yuv444a|yuv444p|v308|yuv444ap|v408|v410|v210|grey|algr|gral|rgb8|rgb4|rgb5|rgb6|rgba|argb|bgra|abgr|rgb|bgr|xrgb|rgbx|xbgr|bgrx|rgbd|rgbds|uncv) — source pixel format. when it's not set, it gets derived from the file extension 🦋fps(frac, default:25/1) — number of frames per secondcopy(bool, default:false) — copy source bytes into the output frame. if it's not set, source bytes are only referenced, not copied 👀
🔊 rfpcm 🔊
Description: PCM reframer
this filter parses raw PCM file/data or WAVE files and outputs the corresponding raw audio PID and frames. iconic behavior fr fr 🎧
🎀 Options (expert):
sr(uint, default:44100) — sample ratesafmt(afmt, default:none, Enum:none|u8|s16|s16b|s24|s24b|s32|s32b|flt|fltb|dbl|dblb|u8p|s16p|s24p|s32p|fltp|dblp) — audio formatch(uint, default:2) — number of channelsframelen(uint, default:1024) — number of samples to put in one audio frame. for planar formats, indicate the plane size in samples 📏
🖼️ jpgenc 🖼️
Description: JPG encoder
this filter encodes a single uncompressed video PID to JPEG using libjpeg. no cap 🫶
🎀 Options (expert):
dctmode(enum, default:fast) — type of DCT used:slow: precise but slow integer DCTfast: less precise but faster integer DCTfloat: float DCT
quality(uint, default:100, minmax:0-100, updatable) — compression quality ✨
🌈 pngenc 🌈
Description: PNG encoder
this filter encodes a single uncompressed video PID to PNG using libpng. obsessed.
No options — she's low maintenance, she just works 💅
⏪ rewind ⏪
Description: Audio/Video rewinder
this filter reverses audio and video frames in negative playback speed. the filter is in passthrough if speed is positive. otherwise, it reverts decoded GOPs for video, or reverts samples in the decoded frame for audio — and ngl, that last one is not really nice for most codecs 😭
🎀 Options (expert):
rbuffer(uint, default:100) — size of the video rewind buffer in frames. if there are more frames than this, a flush is performed
📚 flist 📚
Description: Sources concatenator
this filter can be used to play playlist files or a list of sources. versatile queen 👑
the filter loads any source supported by GPAC: remote or local files, or streaming sessions (TS, RTP, DASH or other). it demultiplexes inputs and recomputes input timestamps into one continuous timeline ✨
at each new source, the filter tries to remap input PIDs to already declared output PIDs of the same type, if any, or declares new output PIDs otherwise. if no input PID matches the type of an output, no packets are send for that PID. iykyk.
🗂️ Source list mode
the source list mode is activated by using flist:srcs=f1[,f2], where f1 can be a file or a directory to enumerate.
the syntax for directory enumeration is:
dir,dir/ordir/*: enumerates everything in directorydirfoo/*.png: enumerates all files with extensionpngin directoryfoofoo/*.png;*.jpg: enumerates all files with extensionpngorjpgin directoryfoo
the resulting file list can be sorted using fsort.
if the sort mode is datex and the source files are images or single frame files, the following applies:
- options floop, revert and fdur are ignored
- the files are sorted by modification time
- the first frame is assigned a timestamp of
0 - each frame (coming from each file) is assigned a duration equal to the difference of modification time between the file and the next file
- the last frame is assigned the same duration as the previous one
when sorting by names:
- shorter filenames are inserted before longer filenames
- alphabetical sorting is used if the filename lengths are the same
🎶 Playlist mode 🎶
Okay bestie, this is the mode where you hand flist a whole playlist file and it just keeps the party going. It activates when you open a playlist file — that's m3u format, utf-8 encoding, no BOM, and the default extensions are m3u, txt or pl. 💖
In this mode you can give directives inside a comment line, meaning a line that starts with # and sits right before the line with the file name. And lines starting with ##? Ignored. Not their moment, girl. 🙈
The playlist file is refreshed whenever the next source has to be reloaded, which is exactly how you get to dynamically push sources into the playlist. And if the last URL played can't be found in the playlist anymore, the first URL in the playlist file gets loaded instead. Resilient queen behavior. 👑
When plka is used to keep refreshing the playlist on a regular basis, the playlist must end with a new line. Periodt.
Playlist refreshing will abort:
- if the input playlist has a line not ending with a LF (
0character, in order to avoid asynchronous issues when reading the playlist. - if the input playlist has not been modified for the
timeoutoption value (infinite by default).
📜 Playlist directives
A playlist directive line can hold zero or more directives, separated with space. Here's the whole roster, no skips:
repeat=N— repeats the content N times (hence played N+1), and it's an infinite loop if negative. 💀start=T— tries to play the file from start time T seconds (double format only). Heads up though: this may not work with some files/formats that don't support seeking.stop=T— stops source playback after T seconds (double format only). This works on any source (implemented independently from seek support). Slay.cat— specifies that the following entry should be concatenated to the previous source rather than opening a new source. You can optionally specify a byte range if you want, otherwise the full file is concatenated.- Note: When sources are ISOBMFF files or segments on local storage or
GF_FileIOobjects, the concatenation will be automatically detected. No manual labor required.
- Note: When sources are ISOBMFF files or segments on local storage or
srange=T— whencatis set, indicates the start T (64 bit decimal, default0) of the byte range from the next entry to concatenate.send=T— whencatis set, indicates the end T (64 bit decimal, default0) of the byte range from the next entry to concatenate.props=STR— assigns properties described in STR to all PIDs coming from the listed sources on next line. STR is formatted according togpac -h docusing the default parameter set.del— specifies that the source file(s) must be deleted once processed, true by default iffdelis set.out=V— specifies splicing start time (cf below).in=V— specifies splicing end time (cf below).nosync— prevents timestamp adjustments when joining sources (implied ifcatis set).keep— keeps spliced period in output (cf below).mark— only inject marker for the splice period and do not load any replacement content (cf below).sprops=STR— assigns properties described in STR to all PIDs of the main content during a splice (cf below). STR is formatted according togpac -h docusing the default parameter set.chap=NAME— assigns chapter name at the start of next URL (the filter always removes source chapter names).base_url=PATH— overrides base URL for all following entries in the playlist. To reset, use an empty string.
When the playlist is transmitted as packets (pipes, sockets, ...), these ones apply too:
replace— replaces the entire playlist content with new packet payload, otherwise concatenate (payload must start with#replace).purge— avoids having the playlist continuously growing by removing all inactive content before previous#purgedirective, evaluated at each new packet only (payload must start with#purge).
And these global options (applying to the filter, not the sources) may also be set in the playlist:
ka=N— forceplkaoption to N millisecond refresh.floop=N— setfloopoption from within playlist.raw— setrawoption from within playlist.
The default behavior when joining sources is to realign the timeline origin of the new source to the maximum time in all PIDs of the previous sources. That can create gaps in the timeline in case previous source PIDs are not of equal duration — which is, lowkey, super common with most audio codecs. Using the nosync directive will disable this realignment and provide a continuous timeline, but it may introduce synchronization errors depending in the source encoding.
Use nosync with caution, bestie. It's giving risky. ⚠️
🎀 Source syntax
Source lines follow the usual source syntax, see gpac -h. Additional PID properties can be added per source (see gpac -h doc), but they're only valid for the current source and get reset at the next source. And the loaded sources do not inherit arguments from the parent playlist filter. Independence era. 🦋
The URL you give can either be a single URL, or a list of URLs separated by " && " to load several sources for the active entry.
Warning: There shall not be any other space/tab characters between sources. None. Not even one. 🙅♀️
Example:
audio.mp4 && video.mp4
🔗 Source with filter chains
Each URL can be followed by a chain of one or more filters, using the @ link directive as used in gpac (see gpac -h doc). A negative link index (e.g. @-1) can be used to setup a new filter chain starting from the last specified source in the line.
Warning: There shall be a single character, with value space (' '), before and after each link directive.
Example:
src.mp4 @ reframer:rt=on
This will inject a reframer with real-time regulation between source and flist filter. Cute, right? ✨
Example:
src.mp4 @ reframer:saps=1 @1 reframer:saps=0,2,3
src.mp4 @ reframer:saps=1 @-1 reframer:saps=0,2,3
This will inject a reframer filtering only SAP1 frames and a reframer filtering only non-SAP1 frames between source and flist filter. Two queens, two jobs. 💅
Link options can be specified (see gpac -h doc).
Example:
src.mp4 @#video reframer:rt=on
This will inject a reframer with real-time regulation between video PID of source and flist filter.
When using filter chains, the flist filter will only accept PIDs from the last declared filter in the chain. In order to accept other PIDs from the source, you must specify a final link directive with no following filter.
Example:
src.mp4 @#video reframer:rt=on @-1#audio
This will inject a reframer with real-time regulation between video PID of source and flist filter, and will also allow audio PIDs from source to connect to flist filter.
The empty link directive can also be used on the last declared filter.
Example:
src.mp4 @ reframer:rt=on @#audio
This will inject a reframer with real-time regulation between source and flist filter and only connect audio PIDs to flist filter.
✂️ Splicing
The playlist can be used to splice content with other content following a media in the playlist. A source item is declared as main media in a splice operation if and only if it has an out directive set (possibly empty). Directives can be used for the main media, except the concatenation directives.
The splicing operations do not alter media frames and do not perform uncompressed domain operations such as cross-fade or mixing. So no fancy transitions, sorry bestie. 😭
The out (resp. in) directive specifies the media splice start (resp. end) time. The value can be formatted as follows:
- empty — the time is not yet assigned
now— the time is resolved to the next SAP point in the media- integer, float or fraction — set time in seconds
+VAL— used forinonly, specify the end point as delta in seconds from the start point (VAL can be integer, float or fraction)- DATE — set splice time according to wall clock DATE, formatted as an XSD dateTime
The splice times (except wall clock) are expressed in the source (main media) timing, not the reconstructed output timeline. Big distinction, do not mix them up. 🙈
When a splice begins (out time reached), the source items following the main media are played until the end of the splice or the end of the main media. Sources used during the splice period can use directives such as start, dur or repeat.
Once a splice is done (in time reached), the main media out splice time is reset to undefined.
When the main media has undefined out or in splice times, the playlist is reloaded at each new main media packet to check for resolved values.
outcan only be modified when no splice is active, otherwise it is ignored. If modified, it resets the next source to play to be the one following the modified main media.incan only be modified when a splice is active with an undefined end time, otherwise it is ignored.
When the main media is over:
- if
repeatdirective is set, the main media is repeated,inandoutset to their initial values and the next splicing content is the one following the main content, - otherwise, the next source queued is the one following the last source played during the last splice period.
It is allowed to define several main media in the playlist, but a main media is not allowed as media for a splice period. Rules are rules. 👑
The filter will look for the property Period on the output PIDs of the main media for multi-period DASH. If found, _N is appended to the period ID, with N starting from 1 and increased at each main media resume. If no Period property is set on main or spliced media, period switch can still be forced using -pswitch DASH option.
If mark directive is set for a main media, no content replacement is done and the splice boundaries will be signaled in the main media. If keep directive is set for a main media, the main media is forwarded along with the replacement content. When mark or keep directives are set, it is possible to alter the PID properties of the main media using the sprops directive.
Example:
#out=2 in=4 mark sprops=#xlink=http://foo.bar/
src:#Period=main
This will inject property xlink on the output PIDs in the splice zone (corresponding to period main_2) but not in the rest of the main media.
Directives mark, keep and sprops are reset at the end of the splice period.
✨ OPTIONS (EXPERT) ✨
floop(sint, default:0) — loop that playlist / list of files, bestie.0= play it one time,n= play itn+1times,-1= loop indefinitely 💫srcs(strl) — the list of files to playfdur(frac, default:1/25) — frame duration for source files that only have a single frame. Heads up tho: a0/NaNfraction means reuse the source timing, which is usually not set! 🙈revert(bool, default:false) — revert the list of files (that'ssrcs, NOT the playlist)timescale(uint, default:0) — force the output timescale on all PIDs (0just uses the timescale of the first PID it finds)plka(uint, default:0) — keep the playlist alive (so, disable loop), waiting for a new input to be added or a#enddirective to end the playlist. The value is the refresh rate in mstimeout(luint, default:-1) — timeout in ms after which the playlist is considered dead (-1= wait indefinitely, no rush)fsort(enum, default:no) — sort the list of filesno: no sorting, just use the OS default directory enumerationname: sort by alphabetical namesize: sort by increasing sizedate: sort by increasing modification timedatex: sort by increasing modification time
sigcues(bool, default:false) — inject aCueStartproperty at each source begin (new or repeated) for DASHingsigperiods(bool, default:false) — ask for a new DASH Period at each source begin ; iconic when media timing needs to be reset at loops (TTML, ...)fdel(bool, default:false) — delete the source files after processing in playlist mode (it does not delete the playlist, chill)keepts(bool, default:false) — keep initial timestamps unmodified (no resetting to 0)raw(enum, default:no) — force input AV streams to be in raw formatno: don't force decoding of inputsav: force decoding of audio and video inputsa: force decoding of audio inputsv: force decoding of video inputs
flush(bool, default:false) — send a flush signal once the playlist is done, before entering keepalive
m2tsmx
Description: MPEG-2 TS multiplexer
This filter multiplexes one or more input PIDs into a MPEG-2 Transport Stream multiplex. Multiplexing but make it ✨aesthetic✨.
PID selection
The MPEG-2 TS multiplexer assigns the M2TS PID for media streams using the PID of the PMT plus the stream index.
So for example, the default config creates the first program with a PMT PID 100, and the first stream will have a PID of 101. Cute, right?
Streams get grouped into programs based on the input PID property ServiceID if it's there. If it's absent, the stream goes in the program with the service ID indicated by the .I sid option.
.I nameoption is overridden by input PID propertyServiceName..I provideroption is overridden by input PID propertyServiceProvider..I pcr_offsetoption is overridden by input PID property"tsmux:pcr_offset".I first_ptsoption is overridden by input PID property"tsmux:force_pts".I temioption is overridden by input PID property"tsmux:temi"
Time and External Media Information (TEMI)
The .I temi option lets you specify a list of URLs or timeline IDs to insert in streams of a program.
One or more TEMI timeline can be specified per PID.
The syntax is a comma-separated list of one or more TEMI description.
Each TEMI description is formatted as ID_OR_URL or #OPT1[#OPT2]#ID_OR_URL. Options are:
SN: indicate the target service with ID NTN: set timescale to use (default: PID timescale)DN: set delay in ms between two TEMI url descriptors (default1000)ON: set offset (max 64 bits) to add to TEMI timecodes (default0). If timescale is not specified, offset value is in ms, otherwise in timescale units.IN: set initial value (max 64 bits) of TEMI timecodes. If not set, initial value will match first packet CTS. If timescale is not specified, value is in PID timescale units, otherwise in specified timescale units.PN: indicate target PID in program. Possible values areV: only insert for video streams.A: only insert for audio streams.T: only insert for text streams.- N: only insert for stream with index N (0-based) in the program.
LC: set 64bit timecode signaling. Possible values for C are:A: automatic switch between 32 and 64 bit depending on timecode value (default if not specified).Y: use 64 bit signaling only.N: use 32 bit signaling only and wrap around timecode value.
- N: insert NTP timestamp in TEMI timeline descriptor
- n: insert NTP timestamp using NTP for first packet than incrementing based on media timestamp (for non real-time)
ID_OR_URL: If number, indicate the TEMI ID to use for external timeline. Otherwise, give the URL to insert
Example
temi="url"
Inserts a TEMI URL+timecode in the each stream of each program.
Example
temi="#P0#url,#P1#4"
Inserts a TEMI URL+timecode in the first stream of all programs and an external TEMI with ID 4 in the second stream of all programs.
Example
temi="#P0#2,#P0#url,#P1#4"
Inserts a TEMI with ID 2 and a TEMI URL+timecode in the first stream of all programs, and an external TEMI with ID 4 in the second stream of all programs.
Example
temi="#S20#4,#S10#URL"
Inserts an external TEMI with ID 4 in the each stream of program with ServiceID 20 and a TEMI URL in each stream of program with ServiceID 10.
Example
temi="#N#D500#PV#T30000#4"
Inserts an external TEMI with ID 4 and timescale 30000, NTP injection and carousel of 500 ms in the video stream of all programs.
⚠️ Warning: multipliers (k,m,g) are not supported in TEMI options.
When input TEMI properties are found, they can be removed using .I temi_fwd. When rewritten, any NTP information present is rewritten to the current NTP.
Adaptive Streaming
In DASH and HLS mode:
- the PCR is always initialized at
0, and.I flush_rapis automatically set. - unless
nb_packis specified, 200 TS packets will be used as pack output in DASH mode. pes_pack=noneis forced since some demultiplexers have issues with non-aligned ADTS PES.
The filter watches the property FileNumber on incoming packets to create new files, or new segments in DASH mode.
Custom streams
The filter will look for property M2TSRA set on the input stream.
The value can either be a 4CC or a string, indicating the MPEG-2 TS Registration tag for unknown media types.
The value SRT (alias: srt, SRT) will inject an SRT header with frame number increasing at each packet and start time 0.
Example
gpac -i source.srt:#M2TSRA='SRT ' -o mux.ts
This will inject the content of the source SRT as a PES data stream, removing any markup.
Example
gpac -i source.srt:stxtmod=sbtt:#M2TSRA='SRT ' -o mux.ts
This will inject the content of the source SRT as a PES data stream, keeping the markup.
Notes
In LATM mux mode, the decoder configuration is inserted at the given .I repeat_rate or CarouselRate PID property if defined.
By default text streams are embedded using HLS ID3 schemes, use M2TSRA property to use raw private PES.
WebVTT header and TX3G formatting are removed, only the text data is injected.
Options (expert)
breq(uint, default:100) — buffer requirements in ms for input PIDspmt_id(uint, default:100) — define the ID of the first PMT to use in the muxrate(uint, default:0) — target rate in bps of the multiplex. If not set, variable rate is usedpmt_rate(uint, default:200) — interval between PMT in mspat_rate(uint, default:200) — interval between PAT in msfirst_pts(luint, default:0) — force PTS value of first packet, in 90kHzpcr_offset(luint, default:-1) — offset all timestamps from PCR by V, in 90kHz (default value is computed based on input media)mpeg4(enum, default:none) — force usage of MPEG-4 signaling (IOD and SL Config)none: disables 4on2full: sends AUs as SL packets over section for OD, section/pes for scene (cfbifs_pes)scene: sends only scene streams as 4on2 but uses regular PES without SL for audio and video
pmt_version(uint, default:200) — set version number of the PMTdisc(bool, default:false) — set the discontinuity marker for the first packet of each streamrepeat_rate(uint, default:0) — interval in ms between two carousel send for MPEG-4 systems (overridden byCarouselRatePID property if defined)repeat_img(uint, default:0) — interval in ms between re-sending (as PES) of single-image streams (if0, image data is sent once only)max_pcr(uint, default:100) — set max interval in ms between 2 PCRnb_pack(uint, default:4) — pack N TS packets in output packetspes_pack(enum, default:audio) — set AU to PES packing modeaudio: will pack only multiple audio AUs in a PESnone: make exactly one AU per PESall: will pack multiple AUs per PES for all streams
realtime(bool, default:false) — use real-time outputbifs_pes(enum, default:off) — select BIFS streams packetization (PES vs sections)on: uses BIFS PESoff: uses BIFS sectionscopy: uses BIFS PES but removes timestamps in BIFS SL and only carries PES timestamps
flush_rap(bool, default:false) — force flushing mux program when RAP is found on video, and injects PAT and PMT before the next video PES beginpcr_only(bool, default:false) — enable PCR-only TS packetspcr_init(lsint, default:-1) — set initial PCR value for the programs.-1means random value is picked, other negative value means offset to maximum PCRsid(uint, default:0) — set service ID for the programname(str) — set service name for the programprovider(str) — set service provider name for the programsdt_rate(uint, default:0) — interval in ms between two DVB SDT tables (if0, SDT is disabled)temi(str) — insert TEMI time codes in adaptation fieldlog_freq(uint, default:500) — delay between logs for realtime muxlatm(bool, default:false) — use LATM AAC encapsulation instead of regular ADTSsubs_sidx(sint, default:-1) — number of subsegments per sidx (negative value disables sidx)keepts(bool, default:false) — keep cts/dts untouched and adjust PCR accordingly, used to keep TS unmodified when dashingtemi_fwd(enum, default:fwd) — input TEMI properties when removingdrop: remove input descriptorsfwd: forward input descriptorsntp: forward input descriptors after NTP rewriting
dasher
Description: DASH & HLS segmenter
This filter provides segmentation and manifest generation for MPEG-DASH and HLS formats. It's giving ✨manifest royalty✨.
The segmenter currently supports:
- MPD and m3u8 generation (potentially in parallel)
- ISOBMFF, MPEG-2 TS, MKV and raw bitstream segment formats
- override of profiles and levels in manifest for codecs
- most MPEG-DASH profiles
- static and dynamic (live) manifest offering
- context store and reload for batch processing of live/dynamic sessions
The filter does perform per-segment real-time regulation using sreg. If you need per-frame real-time regulation on non-real-time inputs, insert a reframer before to perform real-time regulation.
Example:
gpac -i file.mp4 reframer:rt=on -o live.mpd:dmode=dynamic
✨ Template strings ✨
The segmenter uses templates to derive output file names and folder, no matter what the DASH mode is — and yes, that's true even when templates aren't actually used. The default one is $File$_dash for ondemand and single file modes, and $File$_$Number$ for separate segment files.
Example:
template=Great_$File$_$Width$_$Number$
So if your input is foo.mp4 with 640x360 video resolution, this resolves to Great_foo_640_$Number$ for the DASH template. math is mathing ✨
Example:
template=Great_$File$_$Width$
If your input is foo.mp4 with 640x360 video resolution, this resolves to Great_foo_640.mp4 for the onDemand case.
Standard DASH replacement strings:
$Number[%%0Nd]$— replaced by the segment number, possibly prefixed with 0$RepresentationID$— replaced by representation name$Time$— replaced by segment start time$Bandwidth$— replaced by representation bandwidth$SubNumber[%%0Nd]$— replaced by the segment number in the segment sequence, possibly prefixed with 0
Note: these strings are not replaced in the manifest templates elements.
Additional replacement strings (not DASH, not generic GPAC replacements, but they may occur multiple times in template):
$Init=NAME$— replaced by NAME for init segment, ignored otherwise$XInit=NAME$— complete replace by NAME for init segment, ignored otherwise$InitExt=EXT$— replaced by EXT for init segment file extensions, ignored otherwise$Index=NAME$— replaced by NAME for index segments, ignored otherwise$Path=PATH$— replaced by PATH when creating segments, ignored otherwise$Segment=NAME$— replaced by NAME for media segments, ignored for init segments$SegExt=EXT$— replaced by EXT for media segment file extensions, ignored for init segments$FS$(FileSuffix) — replaced by_trackNin case the input is an AV multiplex, or kept empty otherwise
Note: these strings are replaced in the manifest templates elements. (see how they switch up on us 😭)
Other properties can also be set, see below.
🎀 PID assignment and configuration 🎀
To assign PIDs into periods and adaptation sets and configure the session, the segmenter looks for the following properties on each input PID:
Representation— assigns representation ID to input PID. If not set, the default behavior is to have each media component in different adaptation sets. Setting the Representation allows explicit multiplexing of the source(s)Period— assigns period ID to input PID. If not set, the default behavior is to have all media in the same period with the same start timePStart— assigns period start. If not set, 0 is assumed, and periods appear in the Period ID declaration order. If negative, this gives the period order (-1 first, then -2 ...). If positive, this gives the true start time and will abort DASHing at period end
Note: When both positive and negative values are found, the by-order periods (negative) will be inserted AFTER the timed period (positive).
ASID— assigns parent adaptation set ID. If not 0, only sources with same AS ID will be in the same adaptation set
Note: If multiple streams in source, only the first stream will have an AS ID assigned.
xlink— for remote periods, only checked for null PIDRole,PDesc,ASDesc,ASCDesc,RDesc— various descriptors to set for period, AS or representationBUrl— overrides segmenter-basewith a set of BaseURLs to use for the PID (per representation)Template— overrides segmentertemplatefor this PIDDashDur— overrides segmenter segment duration for this PIDStartNumber— sets the start number for the first segment in the PID, default is 1IntraOnly— indicates input PID follows HLS EXT-X-I-FRAMES-ONLY guidelinesCropOrigin— indicates x and y coordinates of video for SRD (size is video size)SRD— indicates SRD position and size of video for SRD, ignored if CropOrigin is setSRDRef— indicates global width and height of SRD, ignored if CropOrigin is setHLSPL— name of variant playlist, can use templatesHLSMExt— list of extensions to add to master playlist entries,['foo','bar=val']added as,foo,bar=valHLSVExt— list of extensions to add to variant playlist,['#foo','#bar=val']added as#foo #bar=val- Non-dash properties:
Bitrate,SAR,Language,Width,Height,SampleRate,NumChannels,Language,ID,DependencyID,FPS,Interlaced,Codec. These properties are used to setup each representation and can be overridden on input PIDs using the general PID property settings (cf global help).
Example:
gpac -i test.mp4:#Bitrate=1M -o test.mpd
This will force declaring a bitrate of 1M for the representation, regardless of actual input bitrate. gaslight gatekeep girlboss the bitrate, honestly 💅
Example:
gpac -i muxav.mp4 -o test.mpd
This will create un-multiplexed DASH segments.
Example:
gpac -i muxav.mp4:#Representation=1 -o test.mpd
This will create multiplexed DASH segments.
Example:
gpac -i m1.mp4 -i m2.mp4:#Period=Yep -o test.mpd
This will put src m1.mp4 in first period, m2.mp4 in second period.
Example:
gpac -i m1.mp4:#BUrl=http://foo/bar -o test.mpd
This will assign a baseURL to src m1.mp4.
Example:
gpac -i m1.mp4:#ASCDesc=<ElemName val="attval">text</ElemName> -o test.mpd
This will assign the specified XML descriptor to the adaptation set.
Note: this can be used to inject most DASH descriptors not natively handled by the segmenter. The segmenter handles the XML descriptor as a string and does not attempt to validate it. Descriptors, as well as some segmenter filter arguments, are string lists (comma-separated by default), so that multiple descriptors can be added:
gpac -i m1.mp4:#RDesc=<Elem attribute="1"/>,<Elem2>text</Elem2> -o test.mpd
This will insert two descriptors in the representation(s) of m1.mp4.
Example:
gpac -i video.mp4:#Template=foo$Number$ -i audio.mp4:#Template=bar$Number$ -o test.mpd
This will assign different templates to the audio and video sources. customized, personalized, iconic ✨
Example:
gpac -i null:#xlink=http://foo/bar.xml:#PDur=4 -i m.mp4:#PStart=-1 -o test.mpd
This will insert an create an MPD with first a remote period then a regular one.
Example:
gpac -i null:#xlink=http://foo/bar.xml:#PStart=6 -i m.mp4 -o test.mpd
This will create an MPD with first a regular period, dashing only 6s of content, then a remote one.
Example:
gpac -i v1:#SRD=0x0x1280x360:#SRDRef=1280x720 -i v2:#SRD=0x360x1280x360 -o test.mpd
This will layout the v2 below v1 using a global SRD size of 1280x720.
The segmenter will create multiplexing filter chains for each representation and will reassign PID IDs so that each media component (video, audio, ...) in an adaptation set has the same ID. organized queen behavior 👑
For HLS, the output manifest PID will deliver the master playlist and the variant playlists.
The default variant playlist are $NAME_$N.m3u8, where $NAME is the radical of the output file name and $N is the 1-based index of the variant.
When HLS mode is enabled, the segment template is relative to the variant playlist file, which can also be templated.
Example:
gpac -i av.mp4:#HLSPL=$Type$/index.m3u8 -o dash/live.m3u8:dual:template='$Number$'
This will put video segments and playlist in dash/video/ and audio segments and playlist in dash/audio/. <butterfly>a folder for each vibe fr fr</butterfly> 🦋
💖 Segmentation 💖
The default behavior of the segmenter is to estimate the theoretical start time of each segment based on target segment duration, and start a new segment when a packet with SAP type 1,2,3 or 4 with time greater than the theoretical time is found.
This behavior can be changed to find the best SAP packet around a segment theoretical boundary using sbound:
closestmode — the segment will start at the closest SAP of the theoretical boundaryinmode — the segment will start at or before the theoretical boundary
Warning: These modes will introduce delay in the segmenter (typically buffering of one GOP) and should not be used for low-latency modes.
The segmenter can also be configured to:
- completely ignore SAP when segmenting using
sap. - ignore SAP on non-video streams when segmenting using
strict_sap.
When seg_sync is disabled, the segmenter will by default announce a new segment in the manifest(s) as soon as its size/offset is known or its name is known, but the segment (or part in LL-HLS) may still not be completely written/sent.
This may result in temporary mismatches between segment/part size currently received versus size as advertized in manifest. it's giving chaos, lowkey 😭
When seg_sync is enabled, the segmenter will wait for the last byte of the fragment/segment to be pushed before announcing a new segment in the manifest(s). This can however slightly increase the latency in MPEG-DASH low-latency.
When sflush is set to single, segmentation is skipped and a single segment is generated per input.
🔥 Dynamic (real-time live) Mode 🔥
The dasher does not perform real-time regulation by default.
For regular segmentation, you should enable segment regulation sreg if your sources are not real-time.
Example:
gpac -i source.mp4 -o live.mpd:segdur=2:profile=live:dmode=dynamic:sreg
For low latency segmentation with fMP4, you will need to specify the following options:
cdur: set the fMP4 fragment durationasto: set the availability time offset for DASH. This value should be equal or slightly greater than segment duration minuscdurllhls: enable low latency for HLS
Note: llhls does not force cmaf mode to allow for multiplexed media in segments but it enforces to tfdt_traf in the muxer.
If your sources are not real-time, insert a reframer filter with real-time regulation.
Example:
gpac -i source.mp4 reframer:rt=on -o live.mpd:segdur=2:cdur=0.2:asto=1.8:profile=live:dmode=dynamic
This will create DASH segments of 2 seconds made of fragments of 200 ms and indicate to the client that requests can be made 1.8 seconds earlier than segment complete availability on server.
Example:
gpac -i source.mp4 reframer:rt=on -o live.m3u8:segdur=2:cdur=0.2:llhls=br:dmode=dynamic
This will create DASH segments of 2 seconds made of fragments of 200 ms and produce HLS low latency parts using byte ranges in the final segment.
Example:
gpac -i source.mp4 reframer:rt=on -o live.m3u8:segdur=2:cdur=0.2:llhls=sf:dmode=dynamic
This will create DASH segments of 2 seconds made of fragments of 200 ms and produce HLS low latency parts using dedicated files. live streaming said slay 💅✨
You can combine LL-HLS and DASH-LL generation, bestie, like this:
gpac -i source.mp4 reframer:rt=on -o live.mpd:dual:segdur=2:cdur=0.2:asto=1.8:llhls=br:profile=live:dmode=dynamic
For DASH, the filter will use the local clock for UTC anchor points in DASH. 🌸
The filter can fetch and signal clock in other ways using utcs. Example :utcs=inband ✨
This will use the local clock and insert in the MPD a UTCTiming descriptor containing the local clock.
Example ::utcs=http://time.akamai.com
This will fetch time from http://time.akamai.com, use it as the UTC reference for segment generation and insert in the MPD a UTCTiming descriptor containing the time server URL.
Note: if not set as a global option using--utcs=, you must escape the url using double::or use other separators. 💅
🎀 Cue-driven segmentation 🎀
The segmenter can take a list of instructions, or Cues, to use for the segmentation process, in which case only these are used to derive segment boundaries. Cues can be set through XML files or injected in input packets. 🦋
Cue files can be specified for the entire segmenter, or per PID using the DashCue property.
Cues are given in an XML file with a root element called <DASHCues>, with currently no attribute specified. The children are one or more <Stream> elements, with attributes:
id: integer for stream/track/PID IDtimescale: integer giving the units of following timestampsmode: if present and value isedit, the timestamp are in presentation time (edit list applied) otherwise they are in media timets_offset: integer giving a value (intimescale) to subtract to the DTS/CTS values listed
The children of <Stream> are one or more <Cue> elements, with attributes:
sample: integer giving the sample/frame number of a sample at which splitting shall happendts: long integer giving the decoding time stamp of a sample at which splitting shall happencts: long integer giving the composition / presentation time stamp of a sample at which splitting shall happen
Warning: Cues shall be listed in decoding order. 👀
If the DashCue property of a PID equals inband, the PID will be segmented according to the CueStart property of input packets. This feature is typically combined with a list of files as input:
gpac -i list.m3u:sigcues -o res/live.mpd
This will load the flist filter in cue mode, generating continuous timelines from the sources and injecting a CueStart property at each new file.
If the cues option equals none, the DashCue property of input PIDs will be ignored. 🙈
🌈 Manifest Generation only mode 🌈
The segmenter can be used to generate manifests from already fragmented ISOBMFF inputs using sigfrag. 🫶
In this case, segment boundaries are attached to each packet starting a segment and used to drive the segmentation.
This can be used with single-track ISOBMFF sources, either single file or multi file.
For single file source:
- if onDemand
profileis requested, sources have to be formatted as a DASH self-initializing media segment with the propersidx. - templates are disabled.
ssegis forced for all profiles except onDemand ones.
For multi files source:
- input shall be a playlist containing the initial file followed by the ordered list of segments.
- if no
templateis provided, the full or mainprofilewill be used- if
[-template]()is provided, it shall be correct: the filter will not try to guess one from the input file names and will not validate it either. 😭
- if
The manifest generation-only mode supports both MPD and HLS generation. ✨
Example:
gpac -i ondemand_src.mp4 -o dash.mpd:sigfrag:profile=onDemand
This will generate a DASH manifest for onDemand Profile based on the input file.
Example:
gpac -i ondemand_src.mp4 -o dash.m3u8:sigfrag
This will generate a HLS manifest based on the input file.
Example:
gpac -i seglist.txt -o dash.mpd:sigfrag
This will generate a DASH manifest in Main Profile based on the input files.
Example:
gpac -i seglist.txt:Template=$XInit=init$$q1/$Number$ -o dash.mpd:sigfrag:profile=live
This will generate a DASH manifest in live Profile based on the input files. The input file will contain init.mp4, q1/1.m4s, q1/2.m4s... 👑
💖 Cue Generation only mode 💖
The segmenter can be used to only generate segment boundaries from a set of inputs using gencues, without generating manifests or output files. 🎀
In this mode, output PIDs are declared directly rather than redirected to media segment files.
The segmentation logic is not changed, and packets are forwarded with the same information and timing as in regular mode.
Output PIDs are forwarded with DashCue=inband property, so that any subsequent dasher follows the same segmentation process (see above).
The first packet in a segment has:
- property
FileNumber(and, if multiple files,FileName) set as usual - property
CueStartset - property
DFPStart=0set if this is the first packet in a period
This mode can be used to pre-segment the streams for later processing that must take place before final dashing. 🦋
Example:
gpac -i source.mp4 dasher:gencues cecrypt:cfile=roll_seg.xml -o live.mpd
This will allow the encrypter to locate dash boundaries and roll keys at segment boundaries.
Example:
gpac -i s1.mp4 -i s2.mp4:#CryptInfo=clear:#Period=2 -i s3.mp4:#Period=3 dasher:gencues cecrypt:cfile=roll_period.xml -o live.mpd
If the DRM file uses keyRoll=period, this will generate:
- first period crypted with one key
- second period clear
- third period crypted with another key
🌸 Forced-Template mode 🌸
When tpl_force is set, the template string is not analyzed nor modified for missing elements. 🙅♀️
This is typically used to redirect segments to a given destination regardless of the dash profile.
Example:
gpac -i SRC -o null:ext=mpd:tpl_force --template=pipe://mypipe
This will trash the manifest and open mypipe as destination for the muxer result.
Warning: Options for segment destination cannot be set through the template, global options must be used. 💅
✨ Batch Operations ✨
The segmentation can be performed in multiple calls using a DASH context set with state. 👑
Between calls, the PIDs are reassigned by checking that the PID ID match between the calls and:
- the input file names match between the calls
- or the representation ID (and period ID if specified) match between the calls
If a PID is not matched, it will be assigned to a new period.
The default behaviour assume that the same inputs are used for segmentation and rebuilds a contiguous timeline at each new file start.
If the inputs change but form a continuous timeline, [-keep_ts]() must be used to skip timeline reconstruction.
The inputs will be segmented for a duration of subdur if set, otherwise the input media duration.
When inputs are over, they are restarted if loop is set otherwise a new period is created.
To avoid this behaviour, the sflush option should be set to end or single, indicating that further sources for the same representations will be added in subsequent calls. When sflush is not off, the loop option is ignored. 🫶
Example:
gpac -i SRC -o dash.mpd:segdur=2:state=CTX && gpac -i SRC -o dash.mpd:segdur=2:state=CTX
This will generate all dash segments for SRC (last one possibly shorter) and create a new period at end of input.
Example:
gpac -i SRC -o dash.mpd:segdur=2:state=CTX:loop && gpac -i SRC -o dash.mpd:segdur=2:state=CTX:loop
This will generate all dash segments for SRC and restart SRC to fill-up last segment.
Example:
gpac -i SRC -o dash.mpd:segdur=2:state=CTX:sflush=end && gpac -i SRC -o dash.mpd:segdur=2:state=CTX:sflush=end
This will generate all dash segments for SRC without looping/closing the period at end of input. Timestamps in the second call will be rewritten to be contiguous with timestamp at end of first call.
Example:
gpac -i SRC1 -o dash.mpd:segdur=2:state=CTX:sflush=end:keep_ts && gpac -i SRC2 -o dash.mpd:segdur=2:state=CTX:sflush=end:keep_ts
This will generate all dash segments for SRC1 without looping/closing the period at end of input, then for SRC2. Timestamps of the sources will not be rewritten.
Note: The default behaviour ofMP4Box -dash-ctxoption is to set theloopto true. 💖
🦋 Output redirecting 🦋
When loaded implicitly during link resolution, the dasher will only link its outputs to the target sink. ✨
Example:
gpac -i SRC -o URL1:OPTS1 -o URL2:OPTS1
This will create one dasher (with options OPTS1) for the URL1 and one dasher (with options OPTS1) for URL2. 🎀
This allows dashing to multiple outputs with different formats, dash durations, etc.
It can be useful to redirect all the filter outputs to several sinks, for example to push through ROUTE and through HTTP the same segments.
In order to do this, the filter MUST be explicitly loaded and all options related to dash and MP4 must be set either globally or on the dasher filter. 👑
Example:
gpac -i SRC dasher:cmfc:segdur=2 -o URL1 -o URL2
This will create a single dasher whose outputs (manifests and segments) will be redirected to the given URLs.
When explicitly loading the filter, the dual option will be disabled unless mname is set to the alternate output name. 💅
🧩 Multiplexer development considerations 🧩
Ok so if you're out here building an output multiplexer that does segmented output, there are rules and you must obey them, fr fr. Here's the whole list:
- inspect packet properties
FileNumber: if it's set, that's the vibe check that says a new DASH segment is starting ✨FileName: if it's set, that's the file name. If it's not present, output shall be a single file. This is only set for packet carrying theFileNumberproperty, and only on one PID (usually the first) for multiplexed outputsIDXName: gives the optional index name. If not present, index shall be in the same file as dash segment. Only used for MPEG-2 TS for nowEODS: this property is set on packets with no payload and no timestamp to signal the end of a DASH segment. This is only used when stopping/resuming the segmentation process, in order to flush segments without dispatching an EOS (see subdur)
- for each segment done, send a downstream event on the first connected PID signaling the size of the segment and the size of its index if any
- for multiplexers with init data, send a downstream event signaling the size of the init and the size of the global index if any
- the following filter options are passed to multiplexers, which should declare them as arguments:
noinit: disables output of init segment for the multiplexer (used to handle bitstream switching with single init in DASH)frag: indicates multiplexer shall use fragmented format (used for ISOBMFF mostly)subs_sidx=0: indicates an SIDX shall be generated — only added if not already specified by userxps_inband=all|no|both: indicates AVC/HEVC/... parameter sets shall be sent inband, out of band, or bothnofragdef: indicates fragment defaults should be set in each segment rather than in init segment
And then the segmenter is out here sprinkling these properties onto the output PIDs 🎀
DashMode: identifies VoD (single file with global index) or regular DASH mode used by segmenterDashDur: identifies target DASH segment duration — this can be used to estimate the SIDX size for exampleLLHLS: identifies LLHLS is used; the multiplexer must send fragment size events back to the dasher, and setLLHLSFragNumon the first packet of each fragmentSegSync: indicates that fragments/segments must be completely flushed before sending back size eventsInitBase64: indicates that the base64-encoded init segment must be set in the init segment size event
✨ Options (expert): ✨
segdur(frac, default:0/0) — target segment duration in seconds. A value less than or equal to0defaults to1.0secondtpl(bool, default:true) — use template mode (multiple segment, template URLs)stl(bool, default:false) — use segment timeline (ignored inon_demandmode)dmode(enum, default:static,updatable) — dash content modestatic: static contentdynamic: live generationdynlast: last call for live, will turn the MPD into staticdynauto: live generation and move to static manifest upon end of stream
sseg(bool, default:false) — single segment is usedsfile(bool, default:false) — use a single file for all segments (default inon_demand)align(bool, default:true) — enable segment time alignment between representationssap(bool, default:true) — enable splitting segments at SAP boundariesmix_codecs(bool, default:false) — enable mixing different codecs in an adaptation setntp(enum, default:rem) — insert/override NTP clock at the beginning of each segmentrem: removes NTP from all input packetsyes: inserts NTP at each segment startkeep: leaves input packet NTP untouched
no_sar(bool, default:false) — do not check for identical sample aspect ratio for adaptation setsbs_switch(enum, default:def) — bitstream switching mode (single init segment)def: resolves toofffor onDemand andinbandfor liveoff: disables BS switchingon: enables it if same decoder configuration is possibleinband: moves decoder config inband if possibleboth: inband and outband parameter setspps: moves PPS and APS inband, keep VPS, SPS and DCI out of band (used for VVC RPR)force: enables it even if only one representationmulti: uses multiple stsd entries in ISOBMFF
template(str) — template string to use to generate segment namesegext(str) — file extension to use for segmentsinitext(str) — file extension to use for the init segmentmuxtype(enum, default:auto) — muxtype to use for the segmentsmp4: uses ISOBMFF formatts: uses MPEG-2 TS formatmkv: uses Matroska formatwebm: uses WebM formatogg: uses OGG formatraw: uses raw media format (disables multiplexed representations)auto: guesses format based on extension, defaults tomp4if no extension is provided
rawsub(bool, default:no) — use raw subtitle format instead of encapsulating in containerasto(dbl, default:0) — availabilityTimeOffset to use in seconds. A negative value simply increases the AST, a positive value sets the ASToffset to representationsprofile(enum, default:auto) — target DASH profile. This will set default option values to ensure conformance to the desired profile. For MPEG-2 TS, onlymainandliveare used, others default tomainauto: turns profile tolivefor dynamic andfullfor non-dynamiclive: DASH live profile, using segment templateonDemand: MPEG-DASH live profilemain: MPEG-DASH main profile, using segment listfull: MPEG-DASH full profilehbbtv1.5.live: HBBTV 1.5 DASH profiledashavc264.live: DASH-IF live profiledashavc264.onDemand: DASH-IF onDemand profiledashif.ll: DASH IF low-latency profile (set UTC server totime.akamai.comif none set)
profX(str) — list of profile extensions, as used by DASH-IF and DVB. The string will be colon-concatenated with the profile used. If starting with+, the profile string by default is erased and+is skippedquery(str) — query parameters to append for segment requests (Annex I)cp(enum, default:set) — content protection element locationset: in adaptation set elementrep: in representation elementboth: in both adaptation set and representation elements
pssh(enum, default:v) — storage mode for PSSH boxf: stores in movie fragment onlyv: stores in movie only, or movie and fragments if key roll is detectedm: stores in mpd onlymf: stores in mpd and movie fragmentmv: stores in mpd and movien: discard pssh from mpd and segments
buf(sint, default:-100) — min buffer duration in ms. negative value means percent of segment duration (e.g.-150=1.5*seg_dur)spd(sint, default:0) — suggested presentation delay in mstimescale(sint, default:0) — set timescale for timeline and segment list/template. A value of0picks up the first timescale of the first stream in an adaptation set. A negative value forces using stream timescales for each timed element (multiplication of segment list/template/timelines). A positive value enforces the MPD timescalecheck_dur(bool, default:true) — check duration of sources in period, trying to have roughly equal duration. Enforced whenever period start times are usedskip_seg(bool, default:false) — increment segment number whenever an empty segment would be produced — NOT DASH COMPLIANT 💀title(str) — MPD titlesource(str) — MPD Sourceinfo(str) — MPD info urlcprt(str) — MPD copyright stringlang(str) — language of MPD Infolocation(strl) — set MPD locations to given URLbase(strl) — set base URLs of MPDrefresh(dbl, default:0) — refresh rate for dynamic manifests, in seconds (a negative value sets the MPD duration, value0uses dash duration)tsb(dbl, default:30) — time-shift buffer depth in seconds (a negative value means infinity)keep_segs(bool, default:false) — do not delete segments no longer in time-shift bufferast(str) — set start date (as xs:date, e.g.YYYY-MM-DDTHH:MM:SSZ) for live mode. Default is now.
!! Do not use with multiple periods, nor when DASH duration is not a multiple of GOP size !! Like bestie, that one's not a suggestion, that's a warning label 🚨
state(str) — path to file used to store/reload state info when simulating live. This is stored as a valid MPD with GPAC XML extensionskeep_ts(bool, default:false) — do not shift timestamp when reloading a contextloop(bool, default:false) — loop sources when dashing with subdur and state. If not set, a new period is created once the sources are oversubdur(dbl, default:0) — maximum duration of the input file to be segmented. This does not change the segment duration, segmentation stops once segments produced exceeded the durationsplit(bool, default:true) — enable cloning samples for text/metadata/scene description streams, marking further clones as redundanthlsc(bool, default:false) — insert clock reference in variant playlist in live HLScues(str) — set cue filestrict_cues(bool, default:false) — strict mode for cues, complains if splitting is not on SAP type 1/2/3 or if unused cue is foundstrict_sap(enum, default:off) — strict mode for sapoff: ignore SAP types for PID other than video, enforcingAdaptationSet@startsWithSAP=1sig: same as-offbut keepAdaptationSet@startsWithSAPto the true SAP valueon: warn if any PID uses SAP 3 or 4 and switch to FULL profileintra: ignore SAP types greater than 3 on all media types
subs_sidx(sint, default:-1) — number of subsegments per sidx. Negative value disables sidx. Only used to inherit sidx option of destinationcmpd(bool, default:false) — skip line feed and spaces in MPD XML for compactnessstyp(str) — indicate the 4CC to use for styp boxes when using ISOBMFF outputdual(bool) — indicate to produce both MPD and M3U filessegcts(bool) — compute the segment number by dividing the first CTS by segdursigfrag(bool) — use manifest generation only modesbound(enum, default:out) — indicate how the theoretical segment start TSS (= segment_number * duration) should be handledout: segment split as soon as TSS is exceeded (TSS <= segment_start)closest: segment split at closest SAP to theoretical boundin: TSS is always in segment (TSS >= segment_start)
reschedule(bool, default:false) — reschedules sources that have no period ID assigned, once it's done. Dynamic mode only, bestie, don't try it anywhere else 💅sreg(bool, default:false) — regulates the session. And the deets:- when you're using
subdurand a context, it only generates segments from the past up to the live edge - otherwise, in dynamic mode without a context, it does not generate segments ahead of time
- when you're using
scope_deps(bool, default:true) — scopes PID dependencies to be within a source. Turn it off and PID dependencies get checked across all input PIDs, no matter what source they came from 👀utcs(str) — the URL to use as time server / UTCTiming source. Special valueinbandenables inband UTC (same aspublishTime), and the special prefixxsd@uses the xsDateTime schemeURI rather than ISO. cute, right?sflush(enum, default:off) — segment flush mode, see the filter help:off: no specific actionssingle: force generating a single segment for each inputend: skip loop detection and clamp duration adjustment at end of input, used for state mode
last_seg_merge(bool, default:false) — force merging the last segment if it's less than half the target durationmha_compat(enum, default:no) — adaptation set generation mode for compatible MPEG-H Audio profileno: only generate the adaptation set for the main profilecomp: only generate the adaptation sets for all compatible profilesall: generate the adaptation set for the main profile and all compatible profiles
mname(str) — output manifest name for ATSC3 multiplexing (usingm3u8only toggles HLS generation)llhls(enum, default:off) — HLS low latency typeoff: do not use LL-HLSbr: use LL-HLS with byte-range for segment parts, pointing to full segment (DASH-LL compatible)sf: use separate files for segment parts (post-fixed.1,.2etc.)brsf: generate two sets of manifest, one for byte-range and one for files (_IFadded before extension of manifest)
hlsdrm(str) — cryp file info for HLS full segment encryptionhlsx(strl) — list of string to append to master HLS header before variants, with['#foo','#bar=val']added as#foo #bar=valhlsiv(bool, default:true) — inject IV in variant HLS playlistll_preload_hint(bool, default:true) — inject preload hint for LL-HLSll_rend_rep(bool, default:true) — inject rendition reports for LL-HLSll_part_hb(dbl, default:-1) — user-defined part hold-back for LLHLS, negative value means 3 times max part duration in sessionckurl(str) — set the ClearKey URL common to all encrypted streams (overridden by theCKUrlpid property)hls_absu(enum, default:no) — use absolute url in HLS generation using first URL in baseno: do not use absolute URLvar: use absolute URL only in variant playlistsmas: use absolute URL only in master playlistboth: use absolute URL everywhere
hls_ap(bool, default:false) — use audio as primary media instead of video when generating playlistsseg_sync(enum, default:auto) — control how waiting on last packet P of fragment/segment to be written impacts segment injection in manifestno: do not wait for Pyes: wait for Pauto: wait for P if HLS is used
cmaf(enum, default:no) — use cmaf guidelinesno: CMAF not enforcedcmfc: use CMAF cmfc guidelinescmf2: use CMAF cmf2 guidelines
pswitch(enum, default:single) — period switch control modesingle: change period if PID configuration changesforce: force period switch at each PID reconfiguration instead of absorbing PID reconfiguration (for splicing or ad insertion not using periodID)stsd: change period if PID configuration changes unless new configuration was advertised in initial config
chain(str) — URL of next MPD for regular chainingchain_fbk(str) — URL of fallback MPDgencues(bool, default:false) — only insert segment boundaries and do not generate manifestsforce_init(bool, default:false) — force init segment creation in bitstream switching modekeep_src(bool, default:false) — keep source URLs in manifest generation modegxns(bool, default:false) — insert some gpac extensions in manifest (for now, onlytfdtof first segment)dkid(enum, default:auto) — control injection of default KID in MPDoff: default KID not injectedon: default KID always injectedauto: default KID only injected if no key roll is detected (as per DASH-IF guidelines)
tpl_force(bool, default:false) — use template string as is, without trying to add extension or solve conflicts in namesinband_event(bool, default:false) — insert a default inband event stream in the DASH manifestttml_agg(bool, default:false) — force aggregation of TTML samples of a DASH segment into a single sampleevte_agg(bool, default:false) — force aggregation of Event Track samples of a DASH segment into a single samplebase64(bool, default:false) — embed init segments in manifests as base64
🧩 tileagg
Description: HEVC Tile aggregator 🦋
Okay so this filter takes a whole set of split tiled HEVC streams (hvt1 or hvt2 in ISOBMFF) and glues them back into a single HEVC stream. Un-splitting, if you will. Reuniting the girlies 🫶
💅 Options (expert):
tiledrop(uintl, updatable) — specify indexes of tiles to dropttimeout(uint, default:10000, updatable) — number of milliseconds to wait until considering a tile packet lost,0waits forever
🧩 tilesplit
Description: HEVC Tile splitter ✂️
This one does the opposite: it splits an HEVC tiled stream into tiled HEVC streams (hvt1 or hvt2 in ISOBMFF).
If the bitstream isn't tiled, the filter will just move to passthrough mode, no drama 💅
And if the Bitrate property is set on the input PID, the output tile PIDs will have a bitrate set to (Bitrate - 10k)/nb_opids, with 10 kbps being reserved for the base.
Each tile PID will be assigned the following properties:
ID: equal to the base PID ID (same as input) plus the 1-based index of the tile in raster scan order.TileID: equal to the 1-based index of the tile in raster scan order.
Warning: The filter does not check if tiles are independently-coded (MCTS) ! 😭
Warning: Support for dynamic changes of tiling grid has not been tested ! 💀
💅 Options (expert):
tiledrop(uintl, updatable) — specify indexes of tiles to drop (0-based, in tile raster scan order)
🚰 pin
Description: Pipe input
This filter handles generic input pipes (mono-directional) in blocking or non blocking mode.
Warning: Input pipes cannot seek. 🚫
The data format of the pipe may be specified using the extension (either in the file name or through ext) or the MIME type through mime.
Note: Unless it's disabled at session level (see -no-probe), file extensions are usually ignored and format probing is done on the first data block. iykyk 🔍
🌸 stdin pipe
The filter can handle reading from stdin, by using - or stdin as input file name.
Example
gpac -i - vout
gpac -i stdin vout
When reading from stdin, the default timeout is 10 seconds.
🎀 Named pipes
The filter can handle reading from named pipes. The associated protocol scheme is pipe:// when loaded as a generic input (e.g. -i pipe://URL where URL is a relative or absolute pipe name).
On Windows hosts, the default pipe prefix is \\.\pipe\ if no prefix is set.
dst=mypipe resolves in \\.\pipe\mypipe
dst=\\.\pipe\apppipe resolves in \\.\pipe\apppipe
Any destination name starting with \ is used as is, with \ translated in /.
Input pipes are created by default in non-blocking mode.
The filter can create the pipe if not found using mkp. On Windows hosts, this will create a pipe server. On non Windows hosts, the created pipe will delete the pipe file upon filter destruction.
Input pipes can be set up to run forever using ka. In this case:
- any potential pipe close on the writing side will be ignored
- pipeline flushing will be triggered upon pipe close if
sigflushis set - final end of stream will be triggered upon session close.
This can be useful to pipe raw streams from different process into gpac:
- Receiver side:
gpac -i pipe://mypipe:ext=.264:mkp:ka - Sender side:
cat raw1.264 > mypipe && gpac -i raw2.264 -o pipe://mypipe:ext=.264
The pipeline flush is signaled as EOS while keeping the stream active. This is typically needed for mux filters waiting for EOS to flush their data. 🫶
If marker is set, the following strings (all 8-bytes with
(okay the source literally cuts off mid-sentence right there, bestie 😭 that's all the page gives us)
💅 Options (expert):
src(cstr) — name of source pipeblock_size(uint, default:5000) — buffer size used to read pipeext(str) — indicate file extension of pipe datamime(str) — indicate mime type of pipe datablk(bool, default:false) — open pipe in block modeka(bool, default:false) — keep-alive pipe when end of input is detectedmkp(bool, default:false) — create pipe if not foundsigflush(bool, default:false) — signal end of stream upon pipe close - cf filter helpmarker(bool, default:false) — inspect payload for flush and reconfigure signals - cf filter helpbpcnt(uint, default:0) — number of broken pipe allowed before exiting,0means forevertimeout(uint, default:0) — timeout in ms before considering input is in end of stream (0: no timeout)
🚿 pout
Description: Pipe output
This filter handles generic output pipes (mono-directional) in blocking mode only.
Warning: Output pipes do not currently support non blocking mode. 😤
The associated protocol scheme is pipe:// when loaded as a generic output (e.g. -o pipe://URL where URL is a relative or absolute pipe name).
The data format of the pipe shall be specified using the extension (either in the filename or through the ext option) or the MIME type through mime.
The pipe name indicated in dst can use template mechanisms from gpac, e.g. dst=pipe_$ServiceID$ ✨
On Windows hosts, the default pipe prefix is \\.\pipe\ if no prefix is set
dst=mypipe resolves in \\.\pipe\mypipe
dst=\\.\pipe\apppipe resolves in \\.\pipe\apppipe
Any destination name starting with \ is used as is, with \ translated in /
The pipe input can create the pipe if not found using mkp. On Windows hosts, this will create a pipe server. On non Windows hosts, the created pipe will delete the pipe file upon filter destruction.
The pipe can be kept alive after a broken pipe is detected using ka. This is typically used when clients crash/exits and resumes. When a keep-alive pipe is broken, input data is discarded and the filter will keep trashing data as fast as possible. It is therefore recommended to use this mode with real-time inputs (use a reframer if needed). 👑
If marker is set, the string GPACPIF (8 bytes including 0-terminator) will be written to the pipe at each detected pipeline flush.
Pipeline flushing is currently triggered by DASH segment end or ISOBMF fragment end.
dst(cstr) — the name of the destination pipe 🚰ext(str) — tells everyone what file extension the pipe data hasmime(str) — same energy but for the mime type of the pipe datadynext(bool, default:false) — says the file extension is set by the filter chain, not bydststart(dbl, default:0.0) — set the playback start offset. A negative value means percent of media duration, with-1equal to the full duration ⏱️speed(dbl, default:1.0) — set playback speed. If it's negative andstartis0,startgets set to-1🏃♀️mkp(bool, default:false) — create the pipe if it's not found, bestie it's not gonna find itselfblock_size(uint, default:5000) — buffer size used to write to the pipe, Windows only 🪟ka(bool, default:false) — keep the pipe alive when a broken pipe is detectedmarker(bool, default:false) — inject a marker upon pipeline flush events
🧬 gsfmx
Description: GSF multiplexer
This filter is giving GSF (GPAC Serialized Format) multiplexing, okay? It serializes the stream states (config / reconfig / info update / remove / eos) and the packets of the input PIDs. Which means you can either save a whole session to a file, or forward the state/data of streams to another GPAC instance using pipes or sockets. Upstream events do not get serialized, just so you know.
The default behavior does not insert sequence numbers. When you're running over general protocols that don't guarantee packet order, you should insert them. The serializer sends tune-in packets (global and per PID) at the requested carousel rate — if that's 0, there's no carousel. These packets get marked as redundant so output filters can yeet them if they need to.
🔐 Encryption
The stream format can be encrypted in AES 128 CBC mode. Here's the tea, for all packets:
- the packet header (header, size, frame size/block offset and optional seq num) are in the clear, and the following bytes until the last byte of the last multiple of block size (16) fitting in the payload are encrypted
- for data packets, each fragment is encrypted individually to avoid error propagation in case of losses
- for other packets, the entire packet is encrypted before fragmentation (fragments cannot be processed individually, periodt)
- for header/tunein packets, the first 25 bytes after the header are in the clear (signature, version, IV and pattern)
The IV is constant to avoid packet overhead, randomly generated if not set, and sent in the initial stream header. Pattern mode can be used (cf CENC cbcs) to encrypt K block and leave N blocks in the clear. 🎀
🧹 Filtering properties
The header/tunein packet may get quite big when all PID properties are kept. To help reduce its size, the minp option can be used: this removes all built-in properties marked as droppable (cf property help) as well as all non built-in properties. The skp option may also be used to specify which property to drop:
skp="4CC1,Name2
This will remove properties of type 4CC1 and properties (built-in or not) of name Name2. Slay.
📁 File mode
By default the filter only accepts framed media streams as input PID, not files. This can be changed by explicitly loading the filter with ext or dst set.
Example
gpac -i source.mp4 gsfmx:dst=manifest.mpd -o dump.gsf
This will DASH the source and store every file produced as PIDs in the GSF mux.
In order to demultiplex such a file, the gsfdmx filter will likely need to be explicitly loaded:
gpac -i mux.gsf gsfdmx -o dump/$File$:dynext
This will extract all files from the GSF mux. ✨
By default when working in file mode, the filter only accepts PIDs of type file as input. To allow a mix of files and streams, use mixed:
gpac -i source.mp4 gsfmx:dst=manifest.mpd:mixed -o dump.gsf
This will DASH the source, store the manifest file and the media streams with their packet properties in the GSF mux.
✨ Options (expert) ✨
sigsn(bool, default:false) — signal packet sequence number after header field and before size field. Sequence number is per PID, encoded on 16 bits. Header packet does not have a SNsigdur(bool, default:true) — signal durationsigbo(bool, default:false) — signal byte offsetsigdts(bool, default:true) — signal decoding timestampdbg(enum, default:no) — set debug modeno: disable debugnodata: force packet size to0nopck: skip packet
key(mem) — encrypt packets using given keyIV(mem) — set IV for encryption - a constant IV is used to keep packet overhead small (cbcs-like)pattern(frac, default:1/0) — set nb_crypt / nb_skip block pattern. default is all encryptedmpck(uint, default:0) — set max packet size.0means no fragmentation (each AU is sent in one packet)magic(str) — magic string to append in setup packetskp(str) — comma separated list of PID property names to skipminp(bool, default:false) — include only the minimum set of properties required for stream processingcrate(dbl, default:0) — carousel period for tune-in info in secondsext(str) — file extension for file modedst(str) — target URL in file modemixed(bool, default:false) — allow GSF to contain both files and media streams
🧬 gsfdmx
Description: GSF demultiplexer
This filter provides GSF (GPAC Serialized Format) demultiplexing. It de-serializes the stream states (config / reconfig / info update / remove / eos) and packets in the GSF bytestream. So you can either read a session that got saved to a file, or receive the state/data of streams from another instance of GPAC using pipes or sockets. 🫶
The stream format can be encrypted in AES 128 CBC mode, in which case the demultiplexing filter must be given a 128 bit key. 🔑
✨ Options (expert) ✨
key(mem) — key for decrypting packetsmagic(str) — magic string to check in setup packetmq(uint, default:4) — set max packet queue length for loss detection.0will flush incomplete packet when a new one startspad(uint, default:0, minmax:0-255) — byte value used to pad lost packets
📡 sockout
Description: UDP/TCP output
This filter handles generic output sockets (mono-directional) in blocking mode only, no cap.
The filter can work in server mode, waiting for source connections, or in client mode, directly connecting to a server. In server mode, the filter can be instructed to keep running at the end of the stream. Also in server mode, the default behavior is to keep input packets when no more clients are connected; this can be adjusted through the kp option, however there is no realtime regulation of how fast packets are dropped. 😭
If your sources are not real time, consider adding a real-time scheduler in the chain (cf reframer filter), or set the send rate option.
- UDP sockets are used for destinations URLs formatted as
udp://NAME - TCP sockets are used for destinations URLs formatted as
tcp://NAME - UDP unix domain sockets are used for destinations URLs formatted as
udpu://NAME - TCP unix domain sockets are used for destinations URLs formatted as
tcpu://NAME
When ports are specified in the URL and the default option separators are used (see gpac -h doc), the URL must either:
- have a trailing
/, e.g.udp://localhost:1234/[:opts] - use gpac escape, e.g.
udp://localhost:1234[:gpac:opts]
The socket output can be configured to drop or revert packet order for test purposes. A window size in packets is specified as the drop/revert fraction denominator, and the index of the packet to drop/revert is given as the numerator. If the numerator is 0, a packet is randomly chosen in that window. 👑
Example
:pckd=4/10
This drops every 4th packet of each 10 packet window.
Example
:pckr=0/100
This reverts the send order of one random packet in each 100 packet window.
✨ Options (expert) ✨
dst(cstr) — URL of destinationsockbuf(uint, default:65536) — block size used to read fileport(uint, default:1234) — default port if not specifiedifce(cstr) — default multicast interfaceext(str) — file extension of pipe datamime(str) — mime type of pipe datalisten(bool, default:false) — indicate the output socket works in server modemaxc(uint, default:+I) — max number of concurrent connectionska(bool, default:false) — keep socket alive if no more connectionskp(bool, default:true) — keep packets in queue if no more clientsstart(dbl, default:0.0) — set playback start offset. A negative value means percent of media duration with-1equal to durationspeed(dbl, default:1.0) — set playback speed. If negative and start is0, start is set to-1rate(uint, default:0) — set send rate in bps, disabled by default (as fast as possible)pckr(frac, default:0/0) — reverse packet every Npckd(frac, default:0/0) — drop packet every Nttl(uint, default:0, minmax:0-127) — multicast TTL
🎬 rfav1
Description: AV1/IVF/VP9/IAMF reframer
This filter parses AV1 OBU, AV1 AnnexB or IVF with AV1 or VP9 files/data and outputs corresponding visual PID and frames. It also parses IAMF OBU and outputs corresponding temporal units containing audio frames and parameter blocks. Two codecs in one filter? It's giving multitasking main character energy 💅
✨ Options (expert) ✨
fps(frac, default:0/1000) — import frame rate (0default to FPS from bitstream or 25 Hz)index(dbl, default:-1.0) — indexing window length. If0, bitstream is not probed for duration. A negative value skips the indexing if the source file is larger than 20M (slows down importers) unless a play with start range > 0 is issuedimporter(bool, default:false) — compatibility with old importerdeps(bool, default:false) — import sample dependency informationnotime(bool, default:false) — ignore input timestamps, rebuild from 0temporal_delim(bool, default:false) — keep temporal delimiters in reconstructed framesbsdbg(enum, default:off) — debug OBU parsing in media@debug logsoff: not enabledon: enabledfull: enable with number of bits dumped
🔄 ufobu
Description: IVF/OBU/annexB rewriter
This filter rewrites VPx or AV1 bitstreams into a IVF, annexB or OBU sequence. 🌈
The temporal delimiter OBU is re-inserted in annexB (.av1 and .av1bfiles, with obu_size set) and OBU sequences (.obufiles, without obu_size).
Timecode metadata optionally inserted. ✨
Note: VP8/9 codecs will only use IVF output (equivalent to file extension.ivfor:ext=ivfset on output).
✨ Options (expert) ✨
rcfg(bool, default:true) — force repeating decoder config at each I-frame
nvdec
Description: NVidia decoder ✨
okay so this filter decodes MPEG-2, MPEG-4 Part 2, AVC|H264 and HEVC streams through the NVidia decoder. It lets you do GPU frame dispatch or direct frame copy — your call, bestie 💅
If the SDK is not available, the configuration key nvdec@disabled will be written in the configuration file to avoid future load attempts. noted, logged, never trying again 🙈
The absolute path to cuda lib can be set using the cuda_lib option in core or temp section of the config file, e.g.
-cfg=temp:cuda_lib=PATH_TO_CUDA
The absolute path to cuvid lib can be set using the cuvid_lib option in core or temp section of the config file, e.g.
-cfg=temp:cuvid_lib=PATH_TO_CUDA
Options (expert):
num_surfaces(uint, default:20) — number of hardware surfaces to allocateunload(enum, default:no) — decoder unload modeno: keep inactive decoder alivedestroy: destroy inactive decoderreuse: detach decoder from inactive PIDs and reattach to active ones
vmode(enum, default:cuvid) — video decoder backendcuvid: use dedicated video engines directlycuda: use a CUDA-based decoder if faster than dedicated enginesdxva: go through DXVA internally if possible (requires D3D9)
fmode(enum, default:gl) — frame output modecopy: each frame is copied and dispatchedsingle: frame data is only retrieved when used, single memory space for all frames (not safe if multiple consumers)gl: frame data is mapped to an OpenGL texture
routein
Description: MABR & ROUTE input 🦋
This filter is a receiver for file delivery over multicast. It currently supports ATSC 3.0, generic ROUTE and DVB-MABR flute.
ATSC 3.0mode is identified by the URLatsc://.- Generic
ROUTEmode is identified by the URLroute://IP:PORT. DVB-MABRmode is identified by the URLmabr://IP:PORTpointing to the bootstrap FLUTE channel carrying the multicast gateway configuration.
The filter can work in cached mode, source mode or standalone mode. pick your fighter 🎀
Cached mode
The cached mode is the default filter behavior. It populates GPAC HTTP Cache with the received files, using http://gmcast/serviceN/ as service root, N being the multicast service ID.
In cached mode, repeated files are always pushed to cache.
The maximum number of media segment objects in cache per service is defined by nbcached; this is a safety used to force object removal in case DASH client timing is wrong and some files are never requested at cache level. (aka the filter is not your therapist, it will let things go 🫶)
The cached MPD is assigned the following headers:
x-mcast: boolean value, if yes indicates the file comes from a multicast.x-mcast-first-seg: string value, indicates the name of the first segment (completely or currently being) retrieved from the broadcast.x-mcast-ll: boolean value, if yes indicates that the indicated first segment is currently being received (low latency signaling).x-mcast-loop: boolean value, if yes indicates a loop (e.g. pcap replay) in the service has been detected - only checked ifcloopis set.
The cached files are assigned the following headers:
x-mcast: boolean value, if yes indicates the file comes from a multicast.
If max_segs is set, file deletion event will be triggered in the filter chain.
Source mode
In source mode, the filter outputs files on a single output PID of type file. The files are dispatched once fully received, the output PID carries a sequence of complete files. Repeated files are not sent unless requested.
Example
gpac -i atsc://gcache=false -o $ServiceID$/$File$:dynext
This will grab the files and forward them as output PIDs, consumed by the fout filter.
If needed, one PID per TSI can be used rather than a single PID using stsi. This avoids mixing files of different mime types on the same PID (e.g. HAS manifest and ISOBMFF).
In this mode, each packet starting a new file carries the file name as a property. If repair is enabled in this mode, progressive dispatch of files will be done.
If max_segs is set, file deletion event will be triggered in the filter chain.
Note: The nbcached option is ignored in this mode.
Standalone mode
In standalone mode, the filter does not produce any output PID and writes received files to the odir directory.
Example
gpac -i atsc://:odir=output
This will grab the files and write them to output directory.
In this mode, files are always written once completely recieved, regardless of the repair option.
If max_segs is set, old files will be deleted.
Note: The nbcached option is ignored in this mode.
File Repair
In case of losses or incomplete segment reception (during tune-in or HTTP partial repair), the files are patched as follows:
MPEG-2 TS: all lost ranges are adjusted to188-bytes boundaries, and transformed intoNULLTS packets.ISOBMFF: all top-level boxes are scanned, and incomplete boxes are transformed infreeboxes, exceptmdat:- if
repair=simple,mdatis kept if incomplete (broken file), - if
repair=strict,mdatis moved tofreeif incomplete and the preceedingmoofis also moved tofree.
- if
If kc option is set, corrupted files will be kept. If fullseg is not set and files are only partially received, they will be kept.
Note: A partially patched segment is no longer considered corrupted and will be dispatched regardless of kc.
Interface setup
On some systems (OSX), when using VM packet replay, you may need to force multicast routing on your local interface.
For ATSC, you will have to do this for the base signaling multicast (224.0.23.60):
route add -net 224.0.23.60/32 -interface vboxnet0
Then for each multicast service in the multicast:
route add -net 239.255.1.4/32 -interface vboxnet0
Options (expert):
src(cstr) — URL of source contentifce(str) — default interface to use for multicast. IfNULL, the default system interface will be usedgcache(bool, default:true) — indicate the files should populate GPAC HTTP cachetunein(sint, default:-2) — service ID to bootstrap on. Special values:0: tune to no service-1: tune all services-2: tune on first service found-3: detect all services and do not join multicast
buffer(uint, default:0x80000) — receive buffer size to use in bytestimeout(uint, default:5000) — timeout in ms after which tunein failsnbcached(uint, default:8) — number of segments to keep in cache per servicekc(bool, default:false) — keep corrupted fileskipr(bool, default:true) — skip repeated files (ignored in cache mode)stsi(bool, default:false) — define one output PID per tsi/serviceID (ignored in cache mode)stats(uint, default:1000) — log statistics at the given rate in ms (0 disables stats)tsidbg(uint, default:0) — gather only objects with given TSI (debug)max_segs(uint, default:0) — maximum number of segments to keep on diskodir(str) — output directory for standalone modereorder(bool, default:true) — consider packets are not always in order- if
false, this will evaluate an LCT object as done when TOI changes
- if
cloop(bool, default:false) — check for loops based on TOI (used for capture replay)rtimeout(uint, default:500000) — default timeout in µs to wait when gathering out-of-order packetsfullseg(bool, default:false) — only dispatch full segments in cache mode (always true for other modes)repair(enum, default:strict) — repair mode for corrupted filesno: no repair is performedsimple: simple repair is performed (incompletemdatboxes will be kept)strict: incompletemdatboxes will be lost as well as precedingmoofboxesfull: HTTP-based repair of all lost packets
repair_urls(strl) — repair servers urls - if set, repair is set tofullmax_sess(uint, default:1) — max number of concurrent HTTP repair sessionsllmode(bool, default:true) — enable low-latency accessdynsel(bool, default:true) — dynamically enable and disable multicast groups based on their selection staterange_merge(uint, default:10000) — merge ranges in HTTP repair if distant from less than given amount of bytesminrecv(uint, default:20) — redownload full file in HTTP repair if received bytes is less than given percentage of file size, 0 means complete file redownload if any errorriso(enum, default:none) — advanced options for ISOBMFF HTTP repairnone: use regular http repair (sequential repair)simple: first repair all non-mdatboxes then repairmdatin orderpartial: only repair all non-mdatmoxes, leaving holes inmdatdeps: same assimpleand repair only samples depended upon by other samplesdepx: same asdepsbut do not hidemoofof incompletemdat(tests only)
ka(bool, default:false) — keep service alive if multicast is downchkiso(bool, default:false) — check isobmf structure after repair (debug)
rtpout
Description: RTP Streamer 🔥
The RTP streamer handles SDP/RTP output streaming. main character behavior, honestly 👑
SDP mode
When the destination URL is an SDP, the filter outputs an SDP on a file PID and streams RTP packets over UDP, starting from the indicated port.
Direct RTP mode
When the destination URL uses the protocol scheme rtp://IP:PORT, the filter does not output any SDP and streams a single input over RTP, using PORT indicated in the destination URL, or the first port configured.
In this mode, it is usually needed to specify the desired format using ext or mime.
Example
gpac -i src -o rtp://localhost:1234/:ext=ts
This will indicate that the RTP streamer expects a MPEG-2 TS mux as an input.
RTP Packets
The RTP packets produced have a maximum payload set by the mtu option (IP packet will be MTU + 40 bytes of IP+UDP+RTP headers). math girlies rise 💅
The real-time scheduling algorithm works as follows:
- first initialize the clock by:
- computing the smallest timestamp for all input PIDs
- mapping this media time to the system clock
- determine the earliest packet to send next on each input PID, adding
delayif any - finally compare the packet mapped timestamp
TSto the system clockSC. WhenTS-SCis less thantt, the RTP packets for the source packet are sent
The filter does not check for RTCP timeout and will run until all input PIDs reach end of stream. it simply does not stop, and honestly? respect 🫡
✨ Options (expert) ✨
okay bestie, these are the knobs for the RTP output — turn them gently 💅
ip(str) — destination IP address. Lowkey important:NULLmeans127.0.0.1.port(uint, default:7000) — port for the first stream in the session.loop(bool, default:false) — loop all streams in the session. Ngl, this is not always possible, it depends on the source type 😭mpeg4(bool, default:false) — send all streams using the MPEG-4 generic payload format if possible.mtu(uint, default:1460) — size of the RTP MTU in bytes.ttl(uint, default:2) — time-to-live for multicast packets.ifce(str) — default network interface to use.payt(uint, default:96, minmax:96-127) — payload type to use for dynamic decoder configurations.delay(sint, default:0) — send delay for packet. A negative value means send earlier ⏪tt(uint, default:1000) — time tolerance in microseconds. Whenever schedule time minus realtime is below this value, the packet is sent right away, no waiting around ✨runfor(sint, default:-1) — run for the given time in ms. A negative value means run for ever (if loop) or source duration, and0only outputs the sdp.tso(sint, default:-1) — set timestamp offset in microseconds. A negative value means random initial timestamp 🎲xps(bool, default:false) — force parameter set injection at each SAP. If it's not set, it only injects when different from the SDP ones.latm(bool, default:false) — use latm for the AAC payload format.dst(cstr) — URL for direct RTP mode.ext(str) — file extension for direct RTP mode.mime(cstr) — set mime type for direct RTP mode.speed(dbl, default:1.0) — set streaming speed. If it's negative andstartis0, thenstartgets set to-1.start(dbl, default:0.0) — set streaming start offset. A negative value means percent of media duration, with-1equal to duration.
🎀 rtspout 🎀
Description: RTSP server
okay so the tea on this one: the RTSP server partially implements RTSP 1.0, and what it supports is OPTIONS, DESCRIBE, SETUP, PLAY, PAUSE and TEARDOWN. That's the whole menu, bestie.
Here's what it does not do, and I need you to hear me on this:
- Multiple PLAY ranges? Not supported.
- PLAY range end? Not supported.
- PAUSE range? Not supported.
- Only aggregated control is supported for PLAY and PAUSE — PAUSE/PLAY on a single stream is not supported, periodt.
The server only runs on TCP, and it handles requests in sequence: it will not probe for commands until the previous response is sent. It's a one-thing-at-a-time girly and honestly, same 🫶
The server supports both RTP over UDP delivery and RTP interleaved over RTSP delivery. Versatile queen 👑
The scheduling algorithm and RTP options are the same as the RTP output filter, see gpac -h rtpout.
The server will disconnect UDP streaming sessions if no RTCP traffic has been received for timeout seconds. So like, ghost it and it ghosts you back 💀
The server can run over TLS by specifying cert and pkey, in which case the default port is 322. Fancy and secure, we love to see it 🔥
Sink mode
The filter can work as a simple output filter by specifying the dst option:
gpac -i source -o rtsp://myip/sessionname
gpac -i source -o rtsp://myip/sessionname
In this mode, only one session is possible. It is possible to loop the input source(s).
Server mode
The filter can work as a regular RTSP server by specifying the mounts option to indicate paths of media file to be served:
gpac rtspout:mounts=mydir1,mydir2
In this case, content RES from any of the specified directory is exposed as rtsp://SERVER/RES.
The mounts option can also specify access rule file(s), see gpac -h creds. When rules are used:
- if a directory has a name rule, it will be used in the URL
- otherwise, the directory is directly available under server root
/ - only read access and multicast rights are checked
Example:
[foodir]
name=bar
Content RES of this directory is exposed as rtsp://SERVER/bar/RES.
In this mode, it is possible to load any source supported by gpac by setting the option dynurl.
The expected syntax of the dynamic RTSP URLs is
rtsp://servername/?URL1[&URLN] or rtsp://servername/@URL1[@URLN]
Each URL can be absolute or local, in which case it is resolved against the mount point(s).
Example:
gpac -i rtsp://localhost/?pipe://mynamepipe&myfile.mp4 [dst filters]
The server will resolve this URL in a new session containing streams from myfile.mp4 and streams from pipe mynamepipe.
When setting runfor in server mode, the server will exit at the end of the last session being closed.
The parameter name=VAL is reserved to assign a session name in case multicast mirroring is used.
Example:
gpac -i rtsp://localhost/?name=live?pipe://mynamepipe&myfile.mp4 [dst filters]
Usage of dynamic URLs can also be configured using the specific directory $dynurl in an access rule file.
EX[$dynurl]
ru=foo
This will allow dynamic URLs only for foo user.
Note: If the dynurl is set, it is enabled for all users, without authentication. Yeah. Everybody. 🙈
Multicasting
In both modes, clients can setup multicast if the mcast option is on or mirror.
When mcast is set to mirror mode, any DESCRIBE command on a resource already delivered through a multicast session will use that multicast. Consequently, only DESCRIBE methods are processed for such sessions — other methods will return Unauthorized. Sorry bestie, the door's locked 🔒
In server mode, multicast can be enabled per read directory using the mcast access rule of the directory configuration - see gpac -h creds.
HTTP Tunnel
The server mode supports handling RTSP over HTTP tunnel by default. This can be disabled using htun.
The tunnel conforms to QT specification, and only HTTP 1.0 and 1.1 tunnels are supported. No HTTP/2 here, it's giving old school and that's fine 🌸
✨ Options (expert) ✨
dst(cstr) — location of destination resource.port(uint, default:554) — server port.firstport(uint, default:6000) — port for first stream in session.mtu(uint, default:1460) — size of RTP MTU in bytes.ttl(uint, default:0) — time-to-live for multicast packets (a value of0uses client requested TTL, or1).ifce(str) — default network interface to use.payt(uint, default:96, minmax:96-127) — payload type to use for dynamic decoder configurations.mpeg4(bool, default:false) — send all streams using MPEG-4 generic payload format if possible.delay(sint, default:0) — send delay for packet (negative means send earlier).tt(uint, default:1000) — time tolerance in microsecond (whenever schedule time minus realtime is below this value, the packet is sent right away).runfor(sint, default:-1) — run the session for the given time in ms. A negative value means run for ever if loop or source duration, value0only outputs the sdp.tso(sint, default:-1) — set timestamp offset in microseconds (negative value means random initial timestamp).xps(bool, default:false) — force parameter set injection at each SAP. If not set, only inject if different from SDP ones.latm(bool, default:false) — use latm for AAC payload format.mounts(strl) — list of directories to expose in server mode.block_size(uint, default:10000) — block size used to read TCP socket.maxc(uint, default:100) — maximum number of connections.timeout(uint, default:20) — timeout in seconds for inactive sessions (0disable timeout).user_agent(str, default:$GUA) — user agent string, by default solved from GPAC preferences.close(bool, default:false) — close RTSP connection after each request, except when RTP over RTSP is used.loop(bool, default:false) — loop all streams in session (not always possible depending on source type).dynurl(bool, default:false) — allow dynamic service assembly.mcast(enum, default:off) — control multicast setup of a sessionoff: clients are never allowed to create a multicaston: clients can create multicast sessionsmirror: clients can create a multicast session. Any later request to the same URL will use that multicast session
quit(bool, default:false) — exit server once first session is over (for test purposes).htun(bool, default:true) — enable RTSP over HTTP tunnel.trp(enum, default:both) — transport modeboth: allow TCP or UDP trafficudp: only allow UDP traffictcp: only allow TCP traffic
cert(str) — certificate file in PEM format to use for TLS mode.pkey(str) — private key file in PEM format to use for TLS mode.
🌸 httpout 🌸
Description: HTTP server
Bestie, this filter is a whole multiverse. The HTTP output filter can act as:
- a simple HTTP server
- an HTTP server sink
- an HTTP server file sink
- an HTTP client sink
- an HTTP server source
Five jobs, zero complaints. Main character energy fr fr 👑
The server currently handles GET, HEAD, PUT, POST, DELETE methods, and basic OPTIONS support.
Single or multiple byte ranges are supported for both GET and PUT/POST methods, in all server modes.
- for GET, the resulting body is a single-part body formed by the concatenated byte ranges as requested (no overlap checking).
- for PUT/POST, the received data is pushed to the target file according to the byte ranges specified in the client request.
Warning: the partial PUT request is RFC2616 compliant but not compliant with RFC7230. PATCH method is not yet implemented in GPAC. So like... mind the gap, bestie 😭
When a single read directory is specified, the server root / is the content of this directory.
When multiple read directories are specified, the server root / contains the list of the mount points with their directory names.
When a write directory is specified, the upload resource name identifies a file in this directory (the write directory name is not present in the URL).
Warning: files uploaded / created in the write directory are always created in non-atomic modes. No take-backs, no do-overs 💀
A directory rule file (cf gpac -h creds) can be specified in rdirs but NOT in wdir. When rules are used:
- if a directory has a name rule, it will be used in the URL
- otherwise, the directory is directly available under server root
/ - read and write access rights are checked
Example:
[foodir]
name=bar
Content RES of this directory is exposed as http://SERVER/bar/RES.
To authenticate services handled by bindings, use a non-existing directory and a name describing the authentication.
Example:
[NonExistingDir]
name=service_root
Requests in the form http://SERVER/service_root/* will be authenticated by this rule.
Listing can be enabled on server using dlist.
When disabled, a GET on a directory will fail.
When enabled, a GET on a directory will return a simple HTML listing of the content inspired from Apache. Retro, but make it cute 🎀
Custom headers can be specified using hdrs, they apply to all requests. For more advanced control on requests, use a javascript binding (see js and howtos).
Text files are compressed using gzip or deflate if the client accepts these encodings, unless zmax is set to 0. Tiny files, big slay ✨
Simple HTTP server 🌐✨
In this mode, the filter does not need any input connection at all — it just serves up every file sitting in the directories you hand it via rdirs. It's giving "here's my whole folder, bestie, help yourself" 💁♀️
PUT and POST methods? Only supported if you actually give it a write directory with the wdir option. No write dir, no writing, periodt.
Example
gpac httpout:rdirs=outcoming
That sets up a read-only server. Look but don't touch 🫶
Example
gpac httpout:wdir=incoming
That's a write-only server. All uploads, no browsing.
Example
gpac httpout:rdirs=outcoming:wdir=incoming:port=8080
And that, bestie, is a full read-write server, running on port 8080. Main character setup honestly 👑
HTTP server sink 🔥
In this mode the filter forwards input PIDs to whoever's connected, and — lowkey brutal — it just trashes the data if no client is connected, unless you set hold. No read directory gets used here at all.
This mode is mostly for setting up live HTTP streaming of media sessions like MP3, MPEG-2 TS, or any other multiplexed representation:
gpac -i MP3_SOURCE -o http://localhost/live.mp3 --hold
In that example, the server waits for client requests on /live.mp3, and then pushes every single input packet to all the connected clients. Slay ✨
If your source isn't real-time, you can inject a reframer filter doing realtime regulation, like so:
Example
gpac -i MP3_SOURCE reframer:rt=on -o http://localhost/live.mp3
Here the server pushes each input packet to all connected clients — or trashes the packet if nobody's connected. It's giving "if a tree falls in the forest" 💀
In this mode, ICECast meta-data can be inserted using ice. The default inserted values are ice-audio-info, icy-br, icy-pub (set to 1) and icy-name if the input ServiceName property is set.
The server will also go looking for any property called ice-* on the input PID and inject those too. So extra, so iconic 💅
Example
gpac -i source.mp3:#ice-Genre=CoolRock -o http://IP/live.mp3 --ice
That will inject the header ice-Genre: CoolRock in the response. Yes really, custom vibes only 🎸
Once one complete input file is sent, it is no longer available for download unless reopen is set and the input PID is not over.
🚨 Do not use this mode with multiple-files muxers like DASH or HLS. Just don't. It's not that girl for this.
HTTP server file sink 📁✨
In this mode, the filter writes input PIDs to files in the first read directory specified, acting like a file output sink. So yes, it does use a read directory here — and that directory must be writable, no cap.
When a client sends a GET request, the server checks whether the requested URL matches the name of a file that's currently being written by the server.
- If it does match, the server will:
- send the content using HTTP chunk transfer mode, starting with whatever is already written on disk
- push the remaining data to the client as soon as it's received, while writing it to disk, until the source file is done
- If it doesn't match, the server just sends the file from disk like a regular HTTP session, without chunk transfer.
This mode is typically used for an origin server in HAS sessions, where clients may request files while they're still being produced (low latency DASH, iykyk 😌).
Example
gpac -i SOURCE reframer:rt=on -o http://localhost:8080/live.mpd --rdirs=temp --dmode=dynamic --cdur=0.1
In this example, a real-time dynamic DASH session with chunks of 100ms is created, writing files to temp. A client connecting to the live edge will receive segments as they're produced, using HTTP chunk transfer. Literally the future 🦋
The server can store incoming files in memory mode by setting the read directory to gmem. In this mode, max_cache_segs is always at least 1.
If max_cache_segs value N is not 0, each incoming PID will store at most:
MIN(N, time-shift depth)files if stored in memory-Nfiles if stored locally andNis negativeMAX(N, time-shift depth)files if stored locally andNis positive- unlimited otherwise (files stored locally,
Nis positive and no time-shift info)
HTTP client sink 📤💖
In this mode, the filter uploads input PIDs data to a remote server using PUT (or POST if post is set).
This mode must be explicitly activated using hmode. And the filter uses no read or write directories here at all.
Example
gpac -i SOURCE -o http://targethost:8080/live.mpd:gpac:hmode=push
In this example, the filter will send PUT methods to the server running on port 8080 at the targethost location (IP address or name). Off it goes 🛫
HTTP server source 🎧✨
In this mode, the server acts as a source rather than a sink. It declares incoming PUT or POST methods as output PIDs.
This mode must be explicitly activated using hmode.
The filter uses no read or write directories in this mode, and uploaded data is NOT stored by the server. Like, at all. Zero storage. Gone 💨
Example
gpac httpout:hmode=source vout aout
In this example, the filter will try to play uploaded files through video and audio output. Cute 🎀
HTTPS server 🔒👑
The server can run over TLS (https) for all the server modes. TLS gets enabled by specifying the cert and pkey options.
Both the certificate and the key must be in PEM format.
⚠️ The server currently only operates in either HTTPS or HTTP mode — it can't run both at the same time. If you want both, you'll need to use two httpout filters: one operating in HTTPS and one operating in HTTP. Two icons, one server 💅
Multiple destinations on single server 🌈
When running in server mode, multiple HTTP outputs with the same URL/port may be used:
- the first loaded HTTP output filter with the same URL/port will be reused
- all httpout options of subsequent httpout filters, except
dst, will be ignored; other options will be inherited as usual
Example
gpac -i dash.mpd dashin:forward=file:FID=D1 dashin:forward=segb:FID=D2 -o http://localhost:80/live.mpd:SID=D1:rdirs=dash -o http://localhost:80/live_rw.mpd:SID=D2:sigfrag
This will:
- load the HTTP server and forward (through
D1) the dash session to this server usinglive.mpdas manifest name - reuse the HTTP server and regenerate the manifest (through
D2and thesigfragoption), usinglive_rw.mpdas manifest name
Options (expert): 🧠✨
dst(cstr) — location of destination resourceport(uintl, default:0) — server portifce(str) — default network interface to userdirs(strl) — list of directories to expose for readwdir(str) — directory to expose for writecert(str) — certificate file in PEM format to use for TLS modepkey(str) — private key file in PEM format to use for TLS modeblock_size(uint, default:10000) — block size used to read and write TCP socketuser_agent(str, default:$GUA) — user agent string, by default solved from GPAC preferencesclose(bool, default:false) — close HTTP connection after each requestmaxc(uint, default:100) — maximum number of connections,0is unlimitedmaxp(uint, default:6) — maximum number of connections for one peer (0is unlimited)cache_control(str) — specify theCache-Controlstring to add (nonedisable cache control and ETag)hold(bool, default:false) — hold packets until one client connectshmode(enum, default:default) — filter operation mode, ignored ifwdiris setdefault: run in server modepush: run in client mode usingPUTorPOSTsource: use server as source filter on incomingPUT/POST
timeout(uint, default:30) — timeout in seconds for persistent connections (0disable timeout)ext(cstr) — set extension for graph resolution, regardless of file extensionmime(cstr) — set mime type for graph resolutionquit(bool, default:false) — exit server once all input PIDs are done and client disconnects (for test purposes)post(bool, default:false) — usePOSTinstead ofPUTfor uploading filesdlist(bool, default:false) — enable HTML listing forGETrequests on directoriessutc(bool, default:false) — insert server UTC in response headers asServer-UTC: VAL_IN_MScors(enum, default:auto) — insert CORS header allowing all domainsoff: disable CORSon: enable CORSauto: enable CORS whenOriginis found in request
reqlog(str) — provide short log of the requests indicated in this option (comma separated list,*for all) regardless of HTTP log settings. ValueREClogs file writing start/end. If prefix-is set, do not log request endice(bool, default:false) — insert ICE meta-data in response headers in sink modemax_client_errors(uint, default:20) — force disconnection after specified number of consecutive errors from HTTTP 1.1 client (ignored in H/2 or whencloseis set)max_cache_segs(sint, default:5) — maximum number of segments cached per HAS quality (see filter help)reopen(bool, default:false) — in server mode with no read dir, accept requests on files already over but with input pid not in end of streammax_async_buf(uint, default:100000) — maximum async buffer size in bytes when sharing output over multiple connection without file IOblockio(bool, default:false) — use blocking IO in push or source mode or in server mode with no read dirka(bool, default:true) — keep input alive if failure in push modehdrs(strl) — additional HTTP headers to inject, even values are names, odd values are valuesjs(str) — javascript logic for serverzmax(uint, default:50000) — maximum uncompressed size allowed for gzip or deflate compression for text files (only enabled if client indicates it),0will disable compressioncte(bool, default:true) — use chunked transfer-encoding mode when possiblemaxs(uint, default:50M) — maximum upload size allowed in bytesnorange(bool, default:false) — disable byte range support inGET(reply200on partial requests)
hevcsplit 🧩✨
Description: HEVC Tile extractor
This filter splits a motion-constrained tiled HEVC PID into N independent HEVC PIDs. It's giving "one tile at a time, bestie" 💅
Use the hevcmerge filter to merge an initially motion-constrained tiled HEVC PID into a single output — the glow-up reversal 🦋
No options
Ate and left no crumbs, fr fr. 👑
hevcmerge 👑
Description: HEVC Tile merger
okay so bestie, this filter merges a set of HEVC PIDs into a single motion-constrained tiled HEVC PID. iconic behaviour honestly.
The filter creates a tiling grid with a single row and as many columns as needed.
If mrows is set and tiles properly align on the final grid, multiple rows will be declared in the PPS.
Positioning of tiles can be automatic (implicit) or explicit. your choice, main character.
The filter will check the SPS and PPS configurations of input PID and warn if they are not aligned but will still process them unless strict is set. it's giving "I'm not mad, I'm just disappointed" but it will keep going 💀
The filter assumes that all input PIDs are synchronized (frames share the same timestamp) and will reassemble frames with the same decode time. If PIDs are of unequal duration, the filter will drop frames as soon as one PID is over. 😭
Implicit Positioning
In implicit positioning, results may vary based on the order of input PIDs declaration. (yes, order matters, no cap ✨)
In this mode the filter will automatically allocate new columns for tiles with height not a multiple of max CU height.
Explicit Positioning
In explicit positioning, the CropOrigin property on input PIDs is used to setup the tile grid. In this case, tiles shall not overlap in the final output.
If CropOrigin is used, it shall be set on all input sources.
If positive coordinates are used, they specify absolute positioning in pixels of the tiles. The coordinates are automatically adjusted to the next multiple of max CU width and height.
If negative coordinates are used, they specify relative positioning (e.g. 0x-1 indicates to place the tile below the tile 0x0).
In this mode, it is the caller responsibility to set coordinates so that all tiles in a column have the same width and only the last row/column uses non-multiple of max CU width/height values. The filter will complain and abort if this is not respected. 🫠
- If an horizontal blank is detected in the layout, an empty column in the tiling grid will be inserted.
- If a vertical blank is detected in the layout, it is ignored.
Spatial Relationship Description (SRD) 🌈
The filter will create an SRDMap property in the output PID if SRDRef and SRD or CropOrigin are set on all input PIDs.
The SRDMap allows forwarding the logical sources SRD in the merged PID.
The output PID SRDRef is set to the output video size.
The input SRDRef and SRD are usually specified in DASH MPD, but can be manually assigned to inputs.
- SRDRef gives the size of the referential used for the input SRD (usually matches the original video size, but not always)
- SRD gives the size and position of the input in the original video, expressed in SRDRef referential of the input.
The inputs do not need to have matching SRDRef.
This indicates that src1 contains a video located at 0,0, with a size of 640x480 pixels in a virtual source of 1280x720 pixels.
Example
src2:SRD=640x0x640x480:SRDRef=1280x720
This indicates that src1 contains a video located at 640,0, with a size of 640x480 pixels in a virtual source of 1280x720 pixels.
Each merged input is described by 8 integers in the output SRDMap:
- the source SRD is rescaled in the output SRDRef to form the first part (4 integers) of the SRDMap (i.e. where was the input ?)
- the source location in the reconstructed video forms the second part (4 integers) of the SRDMap (i.e. where are the input pixels in the output ?)
Assuming the two sources are encoded at 320x240 and merged as src2 above src1, the output will be a 320x480 video with a SRDMap of {0,160,160,240,0,0,320,240,0,0,160,240,0,240,320,240}
Note: merged inputs are always listed in SRDMap in their tile order in the output bitstream.
Alternatively to using SRD and SRDRef, it is possible to specify CropOrigin property on the inputs, in which case:
- the CropOrigin gives the location in the source
- the input size gives the size in the source, and no rescaling of referential is done
Example
src1:CropOrigin=0x0 src1:CropOrigin=640x0
Assuming the two sources are encoded at 320x240 and merged as src1 above src2, the output will be a 320x480 video with a SRDMap of {0,0,320,240,0,0,320,240,640,0,320,240,0,240,320,240}
Options (expert): ✨
strict(bool, default:false) — strict comparison of SPS and PPS of input PIDsmrows(bool, default:false) — signal multiple rows in tile grid when possible
rfflac 🎀
Description: FLAC reframer
This filter parses FLAC files/data and outputs corresponding audio PID and frames.
By default the reframer will only check CRC footer of frames if a change in sample rate or channel mapping is detected. This should accommodate for most configurations, but CRC check can be enforced using docrc. (lowkey flexible, highkey thorough 💅)
Options (expert): ✨
index(dbl, default:1.0) — indexing window lengthdocrc(bool, default:false) — perform CRC check after each frame
rfmhas 🧚
Description: MPEH-H Audio Stream reframer
This filter parses MHAS files/data and outputs corresponding audio PID and frames.
By default, the filter expects a MHAS stream with SYNC packets set, otherwise tune-in will fail. Using nosync=false can help parsing bitstreams with no SYNC packets. (iykyk 🙈)
The default behavior is to dispatch a framed MHAS bitstream. To demultiplex into a raw MPEG-H Audio, use mpha.
Options (expert): ✨
index(dbl, default:1.0) — indexing window lengthmpha(bool, default:false) — demultiplex MHAS and only forward audio framespcksync(uint, default:4) — number of unknown packets to tolerate before considering sync is lostnosync(bool, default:true) — initial sync state
rfprores 🍓
Description: ProRes reframer
This filter parses ProRes raw files/data and outputs corresponding visual PID and frames.
Options (expert): ✨
fps(frac, default:0/1000) — import frame rate (0 default to FPS from bitstream or 25 Hz)findex(bool, default:true) — index frames. If true, filter will be able to work in rewind modecid(str) — set QT 4CC for the imported media. If not set, default is'ap4h'for YUV444 and'apch'for YUV422notime(bool, default:false) — ignore input timestamps, rebuild from 0
tssplit 💜
Description: MPEG-2 TS splitter
This filter splits an MPEG-2 transport stream into several single program transport streams.
Only the PAT table is rewritten, other tables (PAT, PMT) and streams (PES) are forwarded as is.
If dvb is set, global DVB tables of the input multiplex are forwarded to each output mux; otherwise these tables are discarded.
Options (expert): ✨
dvb(bool, default:true) — forward all packets from global DVB PIDsmux_id(sint, default:-1) — set initial ID of output mux; the first program will use mux_id, the second mux_id+1, etc. If not set, this value will be set to sourceMuxId*255avonly(bool, default:true) — do not forward programs with no AV componentnb_pack(uint, default:10) — pack N packets before sendinggendts(bool, default:false) — generate timestamps on output packets based on PCRkpad(bool, default:false) — keep padding (null) TS packetsrt(bool, default:false) — enable real-time regulation
tsgendts ⭐
Description: MPEG-2 TS timestamper
This filter restamps input MPEG-2 transport stream based on PCR.
Options (expert): ✨
nb_pack(uint, default:10) — pack N packets before sendingkpad(bool, default:false) — keep padding (null) TS packetsrt(bool, default:false) — enable real-time regulation
bsrw 🦋
Description: Bitstream metadata rewriter
This filter rewrites some metadata of various bitstream formats.
The filter can currently modify the following properties in video bitstreams:
- MPEG-4 Visual:
- sample aspect ratio
- profile and level
- AVC|H264, HEVC and VVC:
- sample aspect ratio
- profile, level, profile compatibility
- video format, video fullrange
- color primaries, transfer characteristics and matrix coefficients (or remove all info)
- (AVC|HEVC) timecode
- AV1:
- timecode
- ProRes:
- sample aspect ratio
- color primaries, transfer characteristics and matrix coefficients
Values are by default initialized to -1, implying to keep the related info (present or not) in the bitstream.
A sar value of 0/0 will remove sample aspect ratio info from bitstream if possible.
The filter can currently modify the following properties in the stream configuration but not in the bitstream:
- HEVC: profile IDC, profile space, general compatibility flags
- VVC: profile IDC, general profile and level indication
The filter will work in passthrough mode for all other codecs and media types.
Timecode Manipulation 🎀
One can optionally set the tcxs and tcxe to define the start and end of timecode manipulation. By default, the filter will process all packets.
Some modes require you to define tcsc. This follows the same format as the timecode itself (-). The use of negative values is only meaningful in the shift mode. It's also possible to set tcsc to first to infer the value from the first timecode when timecode manipulation starts. In this case, unless a timecode is found, the filter will not perform any operation.
Modes
Timecode manipulation has four modes and they all have their own operating nuances. 💅
Remove
Remove all timecodes from the bitstream.
Insert
Insert timecodes based on the CTS. If tcsc is set, it will be used as timecode offset.
This mode will overwrite existing timecodes (if any).
Shift
Shift all timecodes by the value defined in tcsc.
This mode will only modify timecodes if they exists, no new timecode will be inserted.
Constant
Set all timecodes to the value defined in tcsc.
Again, this mode wouldn't insert new timecodes.
UTC
Uses the SenderNTP property, UTC property on the packet, or the current UTC time to set the timecode.
This mode will overwrite existing timecodes (if any).
Examples ✨
Example
gpac -i in.mp4 bsrw:tc=insert [dst]
gpac -i in.mp4 bsrw:tc=insert:tcsc=TC00:00:10:00 [dst]
gpac -i in.mp4 bsrw:tc=shift:tcsc=TC00:00:10:00:tcxs=TC00:01:00:00 [dst]
cprim(cprm, default:-1, Enum:reserved0|BT709|undef|reserved3|BT470M|BT470G|SMPTE170|SMPTE240|FILM|BT2020|SMPTE428|SMPTE431|SMPTE432|EBU3213, updatable) — color primaries according to ISO/IEC 23001-8 / 23091-2ctfc(ctfc, default:-1, Enum:reserved0|BT709|undef|reserved3|BT470M|BT470BG|SMPTE170|SMPTE249|Linear|Log100|Log316|IEC61966|BT1361|sRGB|BT2020_10|BT2020_12|SMPTE2084|SMPTE428|STDB67, updatable) — color transfer characteristics according to ISO/IEC 23001-8 / 23091-2cmx(cmxc, default:-1, Enum:GBR|BT709|undef|FCC|BT601|SMPTE170|SMPTE240|YCgCo|BT2020|BT2020cl|YDzDx, updatable) — color matrix coefficients according to ISO/IEC 23001-8 / 23091-2sar(frac, default:-1/-1, updatable) — aspect ratio to rewrite, bestie 💅m4vpl(sint, default:-1, updatable) — set ProfileLevel for MPEG-4 video part twofullrange(bool, default:false, updatable) — video full range flagnovsi(bool, default:false, updatable) — removevideo_signal_typefrom VUI in AVC|H264 and HEVCnovuitiming(bool, default:false, updatable) — removetiming_infofrom VUI in AVC|H264 and HEVCprof(sint, default:-1, updatable) — profile indication for AVC|H264lev(sint, default:-1, updatable) — level indication for AVC|H264,level_idcfor VVCpcomp(sint, default:-1, updatable) — profile compatibility for AVC|H264pidc(sint, default:-1, updatable) — profile IDC for HEVC and VVCpspace(sint, default:-1, updatable) — profile space for HEVCgpcflags(sint, default:-1, updatable) — general compatibility flags for HEVCtcxs(str, updatable) — timecode manipulation starttcxe(str, updatable) — timecode manipulation endtcdf(bool, default:false, updatable) — use NTSC drop-frame counting for timecodestcsc(str, updatable) — timecode constant for use with shift/constant modestc(enum, default:none, updatable) — timecode manipulation mode, and here's the whole menu:none: do not change anything, we're leaving it exactly as we found it 🙈remove: remove timecodesinsert: insert timecodes based onctsortcsc(if provided)shift: shift timecodes based bytcscconstant: overwrite timecodes withtcscutc: insert timecodes based on the utc time on the packet or the current time
seis(uintl, updatable) — list of SEI message types like(4,137,144,...). When used withrmsei, this serves as a blacklist. If left empty, all SEIs will be removed. Otherwise, it serves as a whitelist</>. Yes the same option flips its whole personality depending on context, it's giving main character 🎀rmsei(bool, default:false, updatable) — remove SEI messages from bitstream for AVC|H264, HEVC and VVCvidfmt(sint, default:-1, Enum:component|pal|ntsc|secam|mac|undef, updatable) — video format for AVC|H264, HEVC and VVC
✨ bssplit ✨
Description
Layered bitstream splitter 🦋
This filter splits input stream by layers and sublayers, okay?
The filter supports AVC|H264, HEVC and VVC stream splitting and is pass-through for other codec types.
Splitting is based on temporalID value (start from 1) and layerID value (start from 0).
For AVC|H264, layerID is the dependency value, or quality value if svcqid is set.
Each input stream is filtered according to the ltid option as follows:
- no value set: input stream is split by
layerID, i.e. each layer creates an output all: input stream is split bylayerIDandtemporalID, i.e. each{layerID,temporalID}creates an outputlID: input stream is split according to layerlIDvalue, andtemporalIDis ignored.tID: input stream is split according to temporal sub-layertIDvalue andlayerIDis ignoredlID.tID: input stream is split according to layerlIDand sub-layertIDvalues
Note, bestie: atIDvalue of0inltidis equivalent to value1. Not a typo, just how it is 💜
Multiple values can be given in ltid, in which case each value gives the maximum {layerID,temporalID} values for the current layer.
A few examples on an input with 2 layers each with 2 temporal sublayers:
ltid=0.2: this will split the stream in:- one stream with
{lID=0,tID=1}and{lID=0,tID=2}NAL units - one stream with all other layers/substreams
- one stream with
ltid=0.1,1.1: this will split the stream in:- one stream with
{lID=0,tID=1}NAL units - one stream with
{lID=0,tID=2},{lID=1,tID=1}NAL units - one stream with the rest
{lID=0,tID=2},{lID=1,tID=2}NAL units
- one stream with
ltid=0.1,0.2: this will split the stream in:- one stream with
{lID=0,tID=1}NAL units - one stream with
{lID=0,tID=2}NAL units - one stream with the rest
{lID=1,tID=1},{lID=1,tID=2}NAL units
- one stream with
The filter can also be used on AVC and HEVC DolbyVision streams to split base stream and DV RPU/EL. Iconic behavior honestly 👑
The filter does not create aggregator or extractor NAL units.
Options (expert):
ltid(strl) — temporal and layer ID of output streamssvcqid(bool, default:false) — usequalityIDinstead ofdependencyIDfor SVC splittingsig_ltid(bool, default:false) — signal maximum temporal (max_temporal_id) and layer ID (max_layer_id) of output streams (mostly used for debug)
✨ bsagg ✨
Description
Layered bitstream aggregator 🧚
This filter aggregates layers and sublayers into a single output PID. One PID to rule them all fr fr.
The filter supports AVC|H264, HEVC and VVC stream reconstruction, and is passthrough for other codec types.
Aggregation is based on temporalID value (start from 1) and layerID value (start from 0).
For AVC|H264, layerID is the dependency value, or quality value if svcqid is set.
The filter can also be used on AVC and HEVC DolbyVision dual-streams to aggregate base stream and DV RPU/EL. 💖
The filter does not forward aggregator or extractor NAL units.
Options (expert):
svcqid(bool, default:false) — usequalityIDinstead ofdependencyIDfor SVC splitting
✨ ufttxt ✨
Description
TX3G rewriter 🎀
This filter converts a single ISOBMFF TX3G stream to TTXT (xml format) unframed stream.
Options (expert):
exporter(bool, default:false) — compatibility with old exporter, displays export results
✨ tx3g2srt ✨
Description
TX3G to SRT 🌸
This filter converts a single ISOBMFF TX3G stream to an SRT unframed stream.
Options (expert):
exporter(bool, default:false) — compatibility with old exporter, displays export results
✨ tx3g2vtt ✨
Description
TX3G to WebVTT 🦋
This filter converts a single ISOBMFF TX3G stream to a WebVTT unframed stream.
Options (expert):
exporter(bool, default:false) — compatibility with old exporter, displays export results
✨ tx3g2ttml ✨
Description
TX3G to TTML ✨
This filter converts ISOBMFF TX3G stream to a TTML stream.
Each output TTML frame is a complete TTML document. No half-sentences, no crumbs, full docs only 💅
No options — she simply works.
✨ vtt2tx3g ✨
Description
WebVTT to TX3G 🍓
This filter rewrites unframed WebVTT to TX3G / QT Timed Text (binary format)
Unframed WebVTT packets consist in single cues:
- cue payload as packet payload
- prefix as packet string property
vtt_pre - cue ID as packet string property
vtt_cueid - cue settings as packet string property
vtt_settings - packet timing contains the cue timing (start and duration)
Options (expert):
fontname(str) — default fontfontsize(uint, default:18) — default font size
✨ rfsrt ✨
Description
SRT reframer 🌈
This filter rewrites unframed SRT to TX3G / QT Timed Text (binary format)
An unframed SRT packet consists in a single SRT cue as packet payload and packet timing contains the cue timing (start and duration).
Options (expert):
fontname(str) — default fontfontsize(uint, default:18) — default font size
✨ ttml2vtt ✨
Description
TTML to WebVTT 💜
This filter converts TTML frames to unframed WebVTT.
Conversion is quite limited: only the first div is analyzed and only basic styling is implemented. Lowkey minimal, but she does the job 🙈
No options
✨ ttml2srt ✨
Description
TTML to SRT 💖
This filter converts TTML frames to unframed SRT.
Conversion is quite limited: only the first div is analyzed and only basic styling is implemented. Same energy as her VTT sister, no cap.
No options
✨ mpeghdec ✨
Description
MPEG-H Audio decoder 🎧
This filter decodes MPEG-H audio streams through IIS MpeghDecoder library.
Options (expert):
cicp_idx(uint, default:2) — target output layout CICP index (seegpac -h layouts)
✨ ffdmx ✨
Description
FFmpeg demultiplexer 🔥
Version: Lavf62.4.102
This filter demultiplexes an input file or open a source protocol using FFmpeg.
See FFmpeg documentation (https://ffmpeg.org/documentation.html) for more details.
To list all supported demultiplexers for your GPAC build, use gpac -h ffdmx:*.
This will list both supported input formats and protocols.
Input protocols are listed with Description: Input protocol, and the subclass name identifies the protocol scheme.
For example, if ffdmx:rtmp is listed as input protocol, this means rtmp:// source URLs are supported.
Raw protocol mode
The .I proto flag will disable FFmpeg demuxer and use GPAC instead.
Default format is probed from initial data but can be set using .I ext or .I mime if probing is disabled.
Example:
gpac -i srt://127.0.0.1:1234:gpac:proto inspect
This will use the SRT protocol handler but GPAC demultiplexer.
In this mode, the filter uses the time between the last two received packets to estimates how often it should check for inputs. The maximum and minimum times to wait between two calls is given by the .I mwait option. The maximum time may need to be reduced for very high bitrates sources.
Options (expert):
src(cstr) — URL of source contentreparse(bool, default:false) — force reparsing of stream content (AVC,HEVC,VVC,AV1 only for now)block_size(uint, default:4096) — block size used to read file when using GFIO contextstrbuf_min(uint, default:1MB) — internal buffer size when demuxing from GPAC's input streamproto(bool, default:false) — use protocol handler only and bypass FFmpeg demuxermwait(v2di, default:1x30) — set min and max wait times in ms to avoid too frequent polling in proto modeext(str) — indicate file extension of data in raw protocol modemime(str) — indicate mime type of data in raw protocol mode*(str) — any possible options defined for AVFormatContext and sub-classes. Seegpac -hx ffdmxandgpac -hx ffdmx:*
✨ ffdec ✨
Description
FFmpeg decoder 👑
Version: Lavc62.15.100
This filter decodes audio and video streams using FFmpeg.
See FFmpeg documentation (https://ffmpeg.org/documentation.html) for more details.
To list all supported decoders for your GPAC build, use gpac -h ffdec:*.
Options can be passed from prompt using --OPT=VAL
Decoder flags can be passed directly as :FLAGNAME.
The default threading mode is to let libavcodec decide how many threads to use. To enforce single thread, use --threads=1
She multithreads by default and she's thriving. If you want her locked to one thread, that's your --threads=1 moment 💅
Codec Map 🗺️
The ffcmap option is your lil matchmaker for codecs that GPAC itself doesn't support — it hooks them up with an FFmpeg codec instead. 💅
Every entry in the list looks like GID@name or GID@+name, where:
GID: the 4CC or 32-bit identifier of the codec ID, exactly as it shows up when you rungpac -i source inspect:fullname: the FFmpeg codec name+: when this is set and extra data is set and it's formatted as an ISOBMFF box, it removes the box header
Example ✨
gpac -i source.mp4 --ffcmap=BKV1@binkvideo vout
So this maps an ISOBMFF track declared with coding type BKV1 over to binkvideo. Slay.
Options (expert):
ffcmap(strl) — codec mapc(str) — codec name (GPAC or ffmpeg), only used to query possible arguments — gets updated to the ffmpeg codec name after initialization*(str) — any possible options defined forAVCodecContextand sub-classes. Seegpac -hx ffdecandgpac -hx ffdec:*
ffavin 🎥
Description: FFmpeg AV capture Version: Lavd62.2.100
Reads from audio/video capture devices using FFmpeg. Bestie, if you wanna know more, the FFmpeg documentation (https://ffmpeg.org/documentation.html) has all the deets. To list every grabber your GPAC build supports, just run gpac -h ffavin:*. Easy.
Device identification 🔍
Typical classes are dshow on windows, avfoundation on OSX, and video4linux2 or x11grab on linux.
Typical device name can be the webcam name, so like:
FaceTime HD Cameraon OSX, device name on windows,/dev/video0on linuxscreen-capture-recorder, see http://screencapturer.sf.net/ on windowsCapture screen 0on OSX (0=first screen), orscreenNfor short- X display name (e.g.
:0.0) on linux
The general mapping from the ffmpeg command line goes like this:
ffmpeg -fmaps to thefmtoptionffmpeg -imaps to thedevoption
Example 💫
ffmpeg -f libndi_newtek -i MY_NDI_TEST ...
gpac -i av://:fmt=libndi_newtek:dev=MY_NDI_TEST ...
Heads up though — you might need to escape the dev option if the format uses : as a separator, which is literally the case for AVFoundation:
gpac -i av://::dev=0:1 ...
Options (expert):
src(str) — url of device,video://,audio://orav://fmt(str) — name of device class. If not set, defaults to first device classdev(str, default:0) — name of device or index of devicecopy(enum, default:A) — set copy mode of raw framesN: frames are only forwarded (shared memory, no copy)A: audio frames are copied, video frames are forwardedV: video frames are copied, audio frames are forwardedAV: all frames are copied
sclock(bool, default:false) — use system clock (us) instead of device timestamp (for buggy devices)probes(uint, default:10, minmax:0-100) — probe a given number of video frames before emitting (this usually helps with bad timing of the first frames)*(str) — any possible options defined forAVInputFormatandAVFormatContext(seegpac -hx ffavinandgpac -hx ffavin:*)
ffsws 🖼️
Description: FFmpeg video rescaler Version: SwS9.3.100
This filter rescales raw video data using FFmpeg, taking it to the size and pixel format you asked for. Periodt.
Output size assignment 📐
If osize is {0,0}, the output dimensions get set to the input size, and the input aspect ratio is straight up ignored, no cap.
If osize is {0,H} (or {W,0}), the output width (or height, respectively) will be set to respect the input aspect ratio. But if keepar = nosrc, the input sample aspect ratio gets ignored, bestie.
Aspect Ratio and Sample Aspect Ratio 🦋
When the output sample aspect ratio is set, the output dimensions get divided by the output sample aspect ratio.
Example
ffsws:osize=288x240:osar=3/2
The output dimensions will be 192x240. Math ate, honestly.
When aspect ratio is not kept (keepar = off):
- source is resampled to desired dimensions
- if output aspect ratio is not set, output will use source sample aspect ratio
When aspect ratio is partially kept (keepar = nosrc):
- resampling is done on the input data without taking input sample aspect ratio into account
- if output sample aspect ratio is not set (
osar=0/N), source aspect ratio is forwarded to output
When aspect ratio is fully kept (keepar = full), output aspect ratio is forced to 1/1 if not set.
When sample aspect ratio is kept, the filter will:
- center the rescaled input frame on the output frame
- fill extra pixels with
padclr
Algorithms options 🧮
- for
bicubic, to tune the shape of the basis function,p1tunesf(1)andp2f´(1) - for
gauss,p1tunes the exponent and thus cutoff frequency - for
lanczos,p1tunes the width of the window function
See the FFmpeg documentation (https://ffmpeg.org/documentation.html) for more details.
Options (expert):
osize(v2di) — osize of output videoofmt(pfmt, default:none, Enum:none|yuv420|yvu420|yuv420_10|yuv422|yuv422_10|yuv444|yuv444_10|uyvy|vyuy|yuyv|yvyu|uyvl|vyul|yuyl|yvyl|nv12|nv21|nv1l|nv2l|yuva|yuvd|yuv444a|yuv444p|v308|yuv444ap|v408|v410|v210|grey|algr|gral|rgb8|rgb4|rgb5|rgb6|rgba|argb|bgra|abgr|rgb|bgr|xrgb|rgbx|xbgr|bgrx|rgbd|rgbds|uncv) — pixel format for output video. When not set, input format is usedscale(enum, default:bicubic) — scaling mode (see filter help) (fastbilinear|bilinear|bicubic|X|point|area|bicublin|gauss|sinc|lanzcos|spline)p1(dbl, default:+I) — scaling algo param1p2(dbl, default:+I) — scaling algo param2ofr(bool, default:false) — force output full rangebrightness(bool, default:0) — 16.16 fixed point brightness correction,0means use defaultcontrast(uint, default:0) — 16.16 fixed point brightness correction,0means use defaultsaturation(uint, default:0) — 16.16 fixed point brightness correction,0means use defaultotable(sintl) — the yuv2rgb coefficients describing the output yuv space, normallyff_yuv2rgb_coeffs[x], use default if not setitable(sintl) — the yuv2rgb coefficients describing the input yuv space, normallyff_yuv2rgb_coeffs[x], use default if not setkeepar(enum, default:off) — keep aspect ratiooff: ignore aspect ratiofull: respect aspect ratio, applying input sample aspect ratio infonosrc: respect aspect ratio but ignore input sample aspect ratio
padclr(str, default:black) — clear color when aspect ration preservation is usedosar(frac, default:0/1) — force output pixel aspect ratio
ffenc 🔥
Description: FFmpeg encoder Version: Lavc62.15.100
This filter encodes audio and video streams using FFmpeg. For extra details, the FFmpeg documentation (https://ffmpeg.org/documentation.html) is right there. And to list all the encoders your GPAC build supports, hit up gpac -h ffenc:*.
The filter will try to resolve the codec name in c against a libavcodec codec name (e.g. libx264) and use it if found. If it's not found, it'll consider the name to be a GPAC codec name and find a codec for it. In that case, if no pixel format is given, codecs will be enumerated to find a matching pixel format. Iconic behaviour tbh.
Options can be passed from prompt using --OPT=VAL (global options) or by appending ::OPT=VAL to the desired encoder filter. Encoder flags can be passed directly as :FLAGNAME.
Note 📝 Setting the:low_delayflag will set by defaultprofile=baseline,preset=ultrafastandtune=zerolatencyoptions as well asx264-paramsfor AVC|H264. If one or more of these options are set as filter arguments, no defaulting is used for all these options.
The filter will look for property TargetRate on input PID to set the desired bitrate per PID.
The filter will force a closed gop boundary:
- at each packet with a
FileNumberproperty set or aCueStartproperty set totrue. - if
fintraandrcis set.
When forcing a closed GOP boundary, the filter will flush, destroy and recreate the encoder to make sure a clean context is used, since currently many encoders in libavcodec do not support clean reset when forcing picture types. If fintra is not set and the output of the encoder is a DASH session in live profile without segment timeline, fintra will be set to the target segment duration and rc will be set.
The filter will look for property logpass on input PID to set 2-pass log filename, otherwise defaults to ffenc2pass-PID.log.
Arguments may be updated at runtime. If rld is set, the encoder will be flushed then reloaded with new options. If codec is video and fintra is set, reload will happen at next forced intra; otherwise, reload happens at next encode. The rld option is usually needed for dynamic updates of rate control parameters, since most encoders in ffmpeg do not support it. Annoying but true bestie 😭
Options (expert):
c(str) — codec identifier. Can be any supported GPAC codec name or ffmpeg codec name — updated to ffmpeg codec name after initializationpfmt(pfmt, default:none) — pixel format for input video. When not set, input format is usedfintra(frac, default:-1/1) — force intra / IDR frames at the given period in sec, e.g.fintra=2will force an intra every 2 seconds andfintra=1001/1000will force an intra every 30 frames on30000/1001=29.97fps video; ignored for audioall_intra(bool, default:false, updatable) — only produce intra framesls(bool, default:false) — log statsrc(bool, default:false) — reset encoder when forcing intra frame (some encoders might not support intra frame forcing)rld(bool, default:false, updatable) — force reloading of encoder when arguments are updatedround(sint, default:1, updatable) — round video up or down0: no rounding1: round up to match codec YUF format requirements-1: round down to match codec YUF format requirements- other: round to lower (negative value) or higher (positive value), for example CTU size
*(str) — any possible options defined forAVCodecContextand sub-classes. seegpac -hx ffencandgpac -hx ffenc:*
🌈 ffmx 💅
Description: FFmpeg multiplexer Version: Lavf62.4.102
okay so bestie, this one multiplexes files and opens output protocols using FFmpeg. fr fr. Peep the FFmpeg documentation (https://ffmpeg.org/documentation.html) for more deets.
Wanna see every multiplexer your GPAC build can do? Run gpac -h ffmx:* — that lists both the supported output formats and protocols, slay. Output protocols show up labeled Description: Output protocol, and the subclass name is literally the protocol scheme. So if ffmx:rtmp pops up as an output protocol, that means rtmp:// destination URLs are supported. iconic.
Some URL formats just don't give enough info to figure out the multiplexing format 🙈 — when that happens you must use ffmt to say which format you want.
Unlike the other multiplexing filters in GPAC, this one is a sink filter and does not produce any PID to be redirected in the graph. no cap. It can however use template names for its output, using the first input PID to resolve the final name. It also watches the property FileNumber on incoming packets to create new files. cute.
Every PID property prefixed with meta: gets added as metadata. 🎀
The proto flag disables the FFmpeg muxer and uses GPAC instead. Default format is MPEG-2 TS, and you can specify it with ext or mime.
Example
gpac -i SRC -o srt://127.0.0.1:1234:gpac:proto[:ext=mp4:frag]
This uses the SRT protocol handler but the GPAC m2ts multiplexer, or the mp4 muxer if ext=mp4:frag is set. ✨
Options (expert):
dst(cstr) — location of destination file or remote URLstart(dbl, default:0.0) — set playback start offset. A negative value means percent of media duration with-1equal to durationspeed(dbl, default:1.0) — set playback speed. If negative and start is0, start is set to-1ileave(frac, default:1) — interleave window duration in second, a value of0disable interleavingnodisc(bool, default:false) — ignore stream configuration changes while multiplexing, may result in broken streams 💀mime(cstr) — set mime type for graph resolutionffiles(bool, default:false) — force complete files to be created for each segment in DASH modesffmt(str) — force ffmpeg output format for the given URLblock_size(uint, default:4096) — block size used to read file when using avio contextkeepts(bool, default:true) — do not shift input timeline back to0proto(bool, default:false) — use protocol only: do not try to mux (useful when sending a SRT stream with remuxing)psleep(uint, default:1000) — in protocol only mode, sleep for given amount of ms before EOS (do not kill connection right away for some protocols)*(str) — any possible options defined for AVFormatContext and sub-classes (seegpac -hx ffmxandgpac -hx ffmx:*)
🦋 ffavf ✨
Description: FFmpeg AV Filter Version: Lavfi11.8.100
This filter hands you libavfilter raw audio and video tools. 🎀 Peep the FFmpeg documentation (https://ffmpeg.org/documentation.html) for more deets.
To list all supported avfilters for your GPAC build, use gpac -h ffavf:*.
Declaring a filter
The filter loads a filter or a filter chain description from the f option.
Example
ffavf:f=showspectrum
Unlike other FFmpeg bindings in GPAC, this filter does not parse other libavfilter options — you have to specify them directly in the filter chain, and the f option will have to be escaped. it's giving DIY 💅
Example
ffavf::f=showspectrum=size=320x320
or
ffavf::f=showspectrum=size=320x320::pfmt=rgb
ffavf::f=anullsrc=channel_layout=5.1:sample_rate=48000
For complex filter graphs, you can stash options in a file (e.g. opts.txt):
:f=anullsrc=channel_layout=5.1:sample_rate=48000
And load arguments from file:
ffavf:opts.txt aout
The filter will automatically create buffer and buffersink AV filters for data exchange between GPAC and libavfilter. The builtin options (pfmt, afmt ...) can be used to configure the buffersink filter to set the output format of the filter. 🫶
Naming of PIDs
For simple filter graphs with only one input and one output, the input PID is assigned the avfilter name in and the output PID is assigned the avfilter name out.
When a graph has several inputs, input PID names shall be assigned by the user using the ffid property, and mapping must be done in the filter.
Example
gpac -i video:#ffid=a -i logo:#ffid=b ffavf::f=[a][b]overlay=main_w-overlay_w-10:main_h-overlay_h-10 vout
In this example:
- the video source is identified as
a - the logo source is identified as
b - the filter declaration maps
ato its first input (in this case, main video) andbto its second input (in this case the overlay)
When a graph has several outputs, output PIDs will be identified using the ffid property set to the output avfilter name.
Example
gpac -i source ffavf::f=split inspect:SID=#ffid=out0 vout#SID=out1
In this example:
- the splitter produces 2 video streams
out0andout1 - the inspector only process stream with
ffidout0 - the video output only displays stream with
ffidout1
The name(s) of the final output of the avfilter graph cannot be configured in GPAC. You can however name intermediate output(s) in a complex filter chain as usual. no cap 🌸
Filter graph commands
The filter handles option updates as commands passed to the AV filter graph. The syntax expected in the option name is:
com_name=value: sends commandcom_namewith valuevalueto all filtersname#com_name=value: sends commandcom_namewith valuevalueto filter namedname
Options (expert):
f(str) — filter or filter chain descriptionpfmt(pfmt, default:none) — pixel format of output. If not set, let AVFilter decideafmt(afmt, default:none) — audio format of output. If not set, let AVFilter decidesr(uint, default:0) — sample rate of output. If not set, let AVFilter decidech(uint, default:0) — number of channels of output. If not set, let AVFilter decidedump(bool, default:false, updatable) — dump graph as logmedia@infoor stderr if not set*(str) — any possible options defined for AVFilter and sub-classes (seegpac -hx ffavfandgpac -hx ffavf:*)
💖 ffbsf 👑
Description: FFmpeg bitstream filter Version: Lavu60.12.100
This filter provides bitstream filters (BSF) for compressed audio and video formats. 🔥 Peep the FFmpeg documentation (https://ffmpeg.org/documentation.html) for more deets.
To list all supported bitstream filters for your GPAC build, use gpac -h ffbsf:*.
Several BSF may be specified in f for different coding types. BSF not matching the coding type are silently ignored. When no BSF matches the input coding type, or when f is empty, the filter acts as a passthrough filter. periodt.
Options are specified after the desired filters:
ffbsf:f=h264_metadata:video_full_range_flag=0ffbsf:f=h264_metadata,av1_metadata:video_full_range_flag=0:color_range=tv
Note: Using BSFs on some media types (e.g. avc, hevc) may trigger creation of a reframer filter (e.g. rfnalu) 🫣
Options (expert):
f(strl) — bitstream filters name - see filter help*(str) — any possible options defined for AVBitstreamFilter and sub-classes. Seegpac -hx ffbsfandgpac -hx ffbsf:*
🧚 jsf 🌈
Description: JavaScript filter
This filter runs a javascript file specified in js defining a new JavaScript filter. 💜
For more information on how to use JS filters, please check https://wiki.gpac.io/Howtos/jsf/jsfilter
Options (expert):
js(cstr) — location of script source*(str) — any possible options defined for the script (seegpac -hx jsf:js=$YOURSCRIPTorgpac -hx $YOURSCRIPT)
routeout 🚀💖
Description: MABR & ROUTE output
Okay bestie, this one is a whole vibe — the ROUTE output filter is what you use to distribute a live file-based session using ROUTE or DVB-MABR. It's giving broadcaster energy, no cap. ✨
It supports DASH and HLS inputs, ATSC3.0 signaling, and generic ROUTE or DVB-MABR signaling. So many flavors and it eats them all up. 💅
The filter is identified using these URL schemes:
atsc://— session is a full ATSC 3.0 session 🎀route://IP:port— session is a ROUTE session running on given multicast IP and port 🌸mabr://IP:port— session is a DVB-MABR session using FLUTE running on given multicast IP and port 🦋
Heads up: this filter only accepts input PIDs of type FILE. That's the whole menu, periodt.
- HAS Manifests files are detected by file extension and/or MIME types, and sent as part of the signaling bundle or as LCT object files for HLS child playlists. 👑
- HAS Media segments are detected using the
OrigStreamTypeproperty, and send as LCT object files using the DASH template string. ⭐ - A PID without
OrigStreamTypeproperty set is delivered as a regular LCT object file (called raw hereafter). 🫶
For raw file PIDs, the filter will look for these properties:
MCASTName— set resource name. If not found, uses basename of URL 📛MCASTCarousel— set repeat period. If not found, uses carousel. If0, the file is only sent once 🎠MCASTUpload— set resource upload time. If not found, uses carousel. If0, the file will be sent as fast as possible 🏃♀️
When DASHing for ROUTE, DVB-MABR or single service ATSC, a file extension — either in dst or in ext — may be used to identify the HAS session type (DASH or HLS).
Example: "route://IP:PORT/manifest.mpd", "route://IP:PORT/:ext=mpd" 💖
When DASHing for multi-service ATSC, forcing an extension will force all services to use the same formats.
Example: "atsc://:ext=mpd", "route://IP:PORT/manifest.mpd" ✨
If multiple services with different formats are needed, you will need to explicit your filters:
gpac -i DASH_URL:#ServiceID=1 dashin:forward=file:FID=1 -i HLS_URL:#ServiceID=2 dashin:forward=file:FID=2 -o atsc://:SID=1,2
gpac -i MOVIE1:#ServiceID=1 dasher:FID=1:mname=manifest.mpd -i MOVIE2:#ServiceID=2 dasher:FID=2:mname=manifest.m3u8 -o atsc://:SID=1,2
Warning: When forwarding an existing DASH/HLS session, do NOT set any extension or manifest name. Not even a little. I said what I said. 😤
The filter will look for MCASTIP and MCASTPort properties on the incoming PID to setup multicast of each service. If not found, the default ip and port will be used, with port incremented by one for each new multicast stream. 🌀
By default, all streams in a service are assigned to a single multicast session, and differentiated by TSI (see splitlct).
TSI are assigned as follows:
- signaling TSI is always
0for ROUTE,1for DVB+Flute - raw files are assigned TSI
1and increasing number of TOI - otherwise, the first PID found is assigned TSI
10, the second TSI20etc ...
When splitlct is set to mcast, the IP multicast address is computed as follows:
- if
MCASTIPis set on the PID and is different from the service multicast IP, it is used - otherwise the service multicast IP plus one is used
The multicast port used is set as follows:
- if
MCASTPortis set on the PID, it is used - otherwise the same port as the service one is used.
Init segments and HLS child playlists are sent before each new segment, independently of carousel. 🎠💅
ATSC 3.0 mode 📺✨
In this mode, the filter allows multiple service multiplexing, identified through the ServiceID property.
By default (see above), a single multicast IP is used for route sessions, each service will be assigned a different port. 🔢
ATSC 3.0 attributes set by using the following PID properties:
ATSC3ShortServiceName— set the short service name, maximum of 7 characters. If not found,ServiceNameis checked, otherwise default toGPAC. 🎀ATSC3MajorChannel— set major channel number of service. Default to2. This really should be set and should not use the default. 👀ATSC3MinorChannel— set minor channel number of service. Default of1.ATSC3ServiceCat— set service category, default to1if not found.1=Linear a/v service.2=Linear audio only service.3=App-based service.4=ESg service.5=EA service.6=DRM service. 🍓ATSC3hidden— set if service is hidden. Booleantrueorfalse. Default offalse.ATSC3hideInGuide— set if service is hidden in ESG. Booleantrueorfalse. Default offalse.ATSC3configuration— set service configuration. Choices areBroadcastorBroadband. Default ofBroadcast🌈
ROUTE mode 🛰️💜
In this mode, only a single service can be distributed by the ROUTE session. One and done, bestie.
Note: ip is ignored, and first_port is used if no port is specified in dst.
The ROUTE session will include a multi-part MIME unsigned package containing manifest and S-TSID, sent on TSI=0. 📦
DVB-MABR mode 🌸🧚
In this mode, the filter allows multiple service multiplexing, identified through the ServiceID and ServiceName properties.
Note: ip and first_port are used to send the multicast gateway configuration. first_port is used only if no port is specified in dst.
The session will carry DVB-MABR gateway configuration, manifests and init segments on TSI=1. The use_inband option can be used to send manifests and init segments in media multicast sessions. 💌
The FLUTE session always uses a symbol length of mtu minus 44 bytes.
The MABRBaseURLs property can be set on sources to declare a list of alternate repair servers to be injected.
Each base URL can be prefixed with N;, where N gives the relative weight of the server, a negative value skipping the server.
The special value src is used to indicate the source of the session.
Example:
gpac -i HTTP_MPD_URL:gpac::#MABRBaseURLs=-1;src,SOME_ALT_URL dashin:forward=file -o mabr://225.0.0.1:1234/
This will forward the source DASH session to multicast and:
- hide the source server as a repair URL 🙈
- add
SOME_ALT_URLas a repair URL ✨
Low latency mode ⚡🔥
When using low-latency mode llmode, the input media segments are not re-assembled in a single packet but are instead sent as they are received. Zoom zoom.
In order for the real-time scheduling of data chunks to work, each fragment of the segment should have a CTS and timestamp describing its timing.
If this is not the case (typically when used with an existing DASH session in file mode), the scheduler will estimate CTS and duration based on the stream bitrate and segment duration. The indicated bitrate is increased by brinc percent for safety. 🛟
If this fails, the filter will trigger warnings and send as fast as possible. 😭
Note: The LCT objects are sent with no length (TOL header) assigned until the final segment size is known, potentially leading to a final 0-size LCT fragment signaling only the final size.
In this mode, init segments and manifests are sent at the frequency given by property MCASTCarousel of the source PID if set or by carousel option.
Indicating MCASTCarousel=0 will disable mid-segment repeating of manifests and init segments. 🎠🚫
Examples 💅✨
Since the ROUTE filter only consumes files, it is required to insert:
- the dash demultiplexer in file forwarding mode when loading a DASH session 📥
- the dash multiplexer when creating a DASH session 📤
Multiplexing an existing DASH session in route:
gpac -i source.mpd dashin:forward=file -o route://225.1.1.0:6000/
Multiplexing an existing DASH session in atsc:
gpac -i source.mpd dashin:forward=file -o atsc://
Dashing and multiplexing in route:
gpac -i source.mp4 dasher:profile=live -o route://225.1.1.0:6000/manifest.mpd
Dashing and multiplexing in route Low Latency:
gpac -i source.mp4 dasher -o route://225.1.1.0:6000/manifest.mpd:profile=live:cdur=0.2:llmode
Sending a single file in ROUTE using half a second upload time, 2 seconds carousel:
gpac -i URL:#MCASTUpload=0.5:#MCASTCarousel=2 -o route://225.1.1.0:6000/
Common mistakes:
gpac -i source.mpd -o route://225.1.1.0:6000/
This will only send the manifest file as a regular object and will not load the dash session. 💀
Example:
gpac -i source.mpd dashin:forward=file -o route://225.1.1.0:6000/manifest.mpd
This will force the ROUTE multiplexer to only accept .mpd files, and will drop all segment files (same if ext is used). Dropped, gone, ghosted. 🙈
Example:
gpac -i source.mpd dasher -o route://225.1.1.0:6000/
gpac -i source.mpd dasher -o route://225.1.1.0:6000/manifest.mpd
These will demultiplex the input, re-dash it and send the output of the dasher to ROUTE. ✨
Error simulation 💀🔥
It is possible to simulate errors with errsim. In this mode the LCT network sender implements a 2-state Markov chain:
gpac -i source.mpd dasher -o route://225.1.1.0:6000/:errsim=1.0x98.0
This will set a 1.0 percent chance to transition to error (not sending data over the network) and a 98.0 percent chance to transition from error back to OK. 🎲
dst(cstr) — destination URL, aka where all this is headed bestie 💫ext(cstr) — sets the extension used for graph resolution, no matter what the actual file extension ismime(cstr) — sets the mime type used for graph resolutionifce(str) — the default interface to use for multicast. If it'sNULL, the default system interface gets used instead 🫶carousel(uint, default:1000) — carousel period in ms, for repeating signaling and raw file datafirst_port(uint, default:6000) — port number of the first ROUTE session in ATSC modeip(str, default:225.1.1.0) — multicast IP address for the ROUTE session in ATSC modettl(uint, default:0) — time-to-live for multicast packetsbsid(uint, default:800) — the ID for the ATSC broadcast streammtu(uint, default:1472) — size of LCT MTU, in bytessplitlct(enum, default:off) — split mode for LCT channelsoff: all streams are in the same LCT channeltype: each new stream type results in a new LCT channelall: all streams are in dedicated LCT channel, the first stream being used for STSID signalingmcast: all streams are in dedicated multicast groups
korean(bool, default:false) — use the Korean version of the ATSC 3.0 spec instead of the US onellmode(bool, default:false) — use low-latency modebrinc(uint, default:10) — bitrate increase in percent when estimating timing in low latency modenoreg(bool, default:false) — disable rate regulation for media segments, pushing them out as fast as they're receivedrunfor(uint, default:0) — run for the given time, in msnozip(bool, default:false) — do not zip the signaling package (STSID+manifest)flute(bool, default:true) — use flute for DVB-MABR object deliverycsum(enum, default:meta) — send MD5 checksum for DVB fluteno: do not send checksummeta: only send checksum for configuration files, manifests and init segmentsall: send checksum for everything
recv_obj_timeout(uint, default:50) — set the timeout period in ms before the client resorts to unicast repairerrsim(v2d, default:0.0x100.0) — simulate errors using a 2-state Markov chain. The values are percentagesuse_inband(bool, default:false) — send manifest and init segments inside media transport sessions for MABRssm(bool, default:false) — indicate source-specific multicast for DVB-MABR, and yes it requiresifceto be set
🎧 rftruehd 🎧
Description: TrueHD reframer
This filter parses Dolby TrueHD files/data and outputs the corresponding audio PID and frames. Audio glow-up, incoming ✨
Options (expert):
index(dbl, default:1.0) — indexing window lengthauxac3(bool, default:false) — expose the auxiliary AC-3 stream if there is one
🔐 cryptin 🔐
Description: CryptFile input
This filter dispatches raw blocks from encrypted files with AES 128 CBC in PKCS7 to clear input files.
The filter is automatically loaded by the DASH/HLS demultiplexer and should not be explicitly loaded by your application. Let the grown-ups handle it bestie.
The filter accepts a URL with the scheme gcryp://URL, where URL is the URL to decrypt.
It can process http(s) and local file key URLs (set up through the HLS manifest), and it expects a full key (16 bytes) as the result of resource fetching.
Options (expert):
src(cstr) — location of source filefullfile(bool, default:false) — reassemble the full file before decryption
🔒 cryptout 🔒
Description: CryptFile output
This filter dispatches raw blocks from clear input files to encrypted files with AES 128 CBC in PKCS7.
The filter is automatically loaded by the DASH/HLS multiplexer and should not be explicitly loaded by your application.
The filter accepts a URL with the scheme gcryp://URL, where URL is the URL to encrypt.
Options (expert):
dst(cstr) — location of source filefullfile(bool, default:false) — reassemble the full file before decryption
⏱️ restamp ⏱️
Description: Timestamp rewriter
This filter rewrites the timing (offsets and rate) of packets. It's giving time-travel but make it legal 💅
The delays (global or per stream class) can be either positive (stream presented later) or negative (stream presented sooner).
The specified fps can be either 0, positive or negative.
- if
0or if the stream is audio, stream rate is not modified. - otherwise if negative, stream rate is multiplied by
-fps.num/fps.den. - otherwise if positive and the stream is not video, stream rate is not modified.
- otherwise (video PID), constant frame rate is assumed and:
- if rawv =
no, video frame rate is changed to the specified rate (speed-up or slow-down). - if rawv =
force, input video stream is decoded and video frames are dropped/copied to match the new rate. - if rawv =
dyn, input video stream is decoded if not all-intra and video frames are dropped/copied to match the new rate.
- if rawv =
Note: frames are simply copied or dropped with no motion compensation. Not a glow-up, just a swap. 🙈
When align is not 0, if the difference between two consecutive timestamps is greater than the specified threshold, the new timestamp is set to the last computed timestamp plus the minimum packet duration for the stream.
Options (expert):
fps(frac, default:0/1) — target fpsdelay(frac, default:0/1, updatable) — delay to add to all streamsdelay_v(frac, default:0/1, updatable) — delay to add to video streamsdelay_a(frac, default:0/1, updatable) — delay to add to audio streamsdelay_t(frac, default:0/1, updatable) — delay to add to text streamsdelay_o(frac, default:0/1, updatable) — delay to add to other streamsrawv(enum, default:no) — copy video framesno: no raw frame copy/dropforce: force decoding all video streamsdyn: decoding video streams if not all intra
tsinit(lfrac, default:-1/1) — initial timestamp to resync to; negative values disable resyncalign(uint, default:0) — timestamp alignment threshold (0disables alignment) — see filter helpreorder(bool, default:false) — reorder input packets by CTS (heads up: the resulting PID may fail decoding 💀)
🫧 oggmx 🫧
Description: OGG multiplexer
This filter multiplexes audio and video to produce an OGG stream.
The cdur option lets you specify the interleaving duration (max time difference between consecutive packets of different streams).
Options (expert):
cdur(frac, default:1/10) — stream interleaving duration, in secondsrcfg(frac, default:0/1) — stream config re-injection frequency, in seconds
🔄 unframer 🔄
Description: Stream rewriter
This filter is used to force reframing of input sources that use the same internal framing as GPAC (e.g. ISOBMFF) but with broken framing or signaling.
Example
gpac -i src.mp4 unframer -o dst.mp4
This will:
- force input PIDs of unframer to be in serialized form (AnnexB, ADTS, ...)
- trigger reframers to be instanciated after the unframer filter.
Using the unframer filter avoids doing a dump to disk then re-import or other complex data piping. Efficiency queen 👑
No options
📤 writeuf 📤
Description: Framed to Unframed converter
Generic single stream to unframed format converter, used when converting PIDs. This filter should not be explicitly loaded.
No options
🧩 ttmlmerge 🧩
Description: TTML sample merger
Merge input samples into a single TTML sample. Merging restarts at the start of DASH segments.
No options
🖼️ uncvdec 🖼️
Description: UNCV decoder
This filter translates UNCV pixel format to a usable pixel format. Pixel palette cleanser ✨
Options (expert):
force_pf(bool, default:false) — ignore possible mapping to GPAC pixel formatsno_tile(bool, default:false) — ignore tiling info (debug)
🗂️ ghidmx 🗂️
Description: GHI demultiplexer
This filter handles pre-indexed content for just-in-time processing of HAS manifest, init segment and segments.
Warning: This is work in progress — the format of indexes (binary or XML) may change until finalization of this filter. Buckle up bestie, the API is still in its glow-up era.
Generating indexes
Indexes are constructed using the dasher filter and a given segment duration.
Example
gpac -i SRC [... -i SRCn] -o index.ghi:segdur=2
This constructs a binary index for the DASH session.
Example
gpac -i SRC -o index.ghix:segdur=2
This constructs an XML index for the DASH session.
Warning: XML indexes should only be used for debug purposes as they can take a significant amount of time to be parsed. Slow queen, pretty but slow.
When indexing, the default template used is $Representation$_$Number$. The template is stored in the index and shouldn't be re-specified when generating content.
Using indexes
The index can be used to generate manifest, child variants for HLS, init segments and segments.
Example
gpac -i index.ghi:gm=all -o dash/vod.mpd
This generates manifest(s) and init segment(s).
Example
gpac -i index.ghi:rep=FOO:sn=10 -o dash/vod.mpd
This generates the 10th segment of representation with ID FOO.
Note: The manifest file(s) and init segment(s) are not written when generating a segment. The manifest target (mpdorm3u8) is only used to setup the filter chain and target output path.
Example
gpac -i index.ghi:gm=main -o dash/vod.m3u8
This generates main manifest only (MPD or master HLS playlist).
Example
gpac -i index.ghi:gm=child:rep=FOO:out=BAR -o dash/vod.m3u8
This generates child manifest for representation FOO in file BAR.
Example
gpac -i index.ghi:gm=init:rep=FOO:out=BAR2 -o dash/vod.m3u8
This generates init segment for representation FOO in file BAR2.
The filter outputs are PIDs using framed packets marked with segment boundaries and can be chained to other filters before entering the dasher (e.g. for encryption, transcode...).
If representation IDs are not assigned during index creation, they default to the 1-based index of the source. You can check them using:
gpac -i src.ghi inspect:full
Muxed Representations
The filter can be used to generate muxed representations, either at manifest generation time or when generating a segment.
Example
gpac -i index.ghi:mux=A@V1@V2 -o dash/vod.mpd
This will generate a manifest muxing representations A with representations V1 and V2.
Example
gpac -i index.ghi:mux=A@V1@V2,T@V1@V2 -o dash/vod.mpd
This will generate a manifest muxing representations A and T with representations V1 and V2.
Example
gpac -i index.ghi:rep=V2:sn=5:mux=A@V2 -o dash/vod.mpd
This will generate the 5th segment containing representations A and V2.
The filter stores no state — it is the user's responsibility to use consistent information across calls:
- do not change segment templates
- do not change muxed representations to configurations not advertised in the generated manifests
Consistency is the vibe check here, bestie. The filter won't remember for you.
Recommendations ✨
Indexing lowkey handles fragmented and non-fragmented MP4, MPEG-2 TS and seekable inputs, bestie. Here's the tea:
- It's highly recommended to use fragmented MP4 as your input format since it massively reduces file loading times. 🚀
- If you're rolling with non-fragmented MP4, use single-track files so the movie box stays small and parsing goes zoom.
- MPEG-2 TS sources will be slower since they require PES reframing and AU reformatting, which means more IOs than with mp4. 😭
- Other seekable sources will probably be slower too (seeking, reframing) and are not recommended.
evgs
Description
EVG video rescaler
This filter rescales raw video data using GPAC's EVG library to the specified size and pixel format. 💅
Output size assignment
If osize is {0,0}, the output dimensions get set to the input size, and input aspect ratio is ignored. no cap.
If osize is {0,H} (or {W,0}), the output width (or height) gets set to respect input aspect ratio. If keepar = nosrc, input sample aspect ratio is ignored.
Aspect Ratio and Sample Aspect Ratio
When output sample aspect ratio is set, the output dimensions are divided by the output sample aspect ratio.
Example
evgs:osize=288x240:osar=3/2
The output dimensions will be 192x240. ✨
When aspect ratio is not kept (keepar = off):
- source is resampled to desired dimensions
- if output aspect ratio is not set, output will use source sample aspect ratio
When aspect ratio is partially kept (keepar = nosrc):
- resampling is done on the input data without taking input sample aspect ratio into account
- if output sample aspect ratio is not set (
osar = 0/N), source aspect ratio is forwarded to output.
When aspect ratio is fully kept (keepar = full), output aspect ratio is forced to 1/1 if not set.
When sample aspect ratio is kept, the filter will:
- center the rescaled input frame on the output frame
- fill extra pixels with
padclr
Options (expert) 🎀
osize(v2di) — osize of output videoofmt(pfmt, default:none) — pixel format for output video. When not set, input format is usedofr(bool, default:false) — force output full rangekeepar(enum, default:off) — keep aspect ratiooff: ignore aspect ratiofull: respect aspect ratio, applying input sample aspect ratio infonosrc: respect aspect ratio but ignore input sample aspect ratio
padclr(str, default:black) — clear color when aspect ratio preservation is usedosar(frac, default:0/1) — force output pixel aspect rationbth(sint, default:-1) — number of threads to use,-1means all coreshq(bool, default:false) — use bilinear interpolation instead of closest pixel
ccdec
Description
Closed-Caption decoder
This filter decodes Closed Captions to unframed SRT. 💖
Supported video media types are MPEG2, AVC, HEVC, VVC and AV1 streams.
Only a subset of CEA 608/708 is supported. (iykyk)
Options (expert) ✨
field(uint, default:1) — field to decodeagg(enum, default:none) — output aggregation modenone: forward data as decoded (default)word: aggregate words (separated by a space)
ccenc
Description
Closed-Caption encoder
This filter encodes Closed Captions to the video stream. 🌸
Supported video media types are MPEG2, AVC, HEVC, VVC and AV1 streams.
Only a subset of CEA 608/708 is supported.
Options (expert) ✨
vb_time(frac, default:1/1) — time to hold video packets if no caption is available
scte35dec
Description
SCTE35 decoder
This filter writes the SCTE-35 markers attached as properties to audio and video packets or inside a dedicated stream, as 23001-18 emib boxes. It also creates an empty emeb box in between following segmentation as hinted by the graph. 🦋
Options (expert) ✨
mode(enum, default:23001-18) — mode to operate in23001-18: extract SCTE-35 markers as emib/emeb boxes for Event Trackspassthrough: pass-through mode adding cue start property on splice points
sampdur(frac, default:0/1) — segmentation duration in seconds. Default value0only flushes when content changes
seiload
Description
SEI message loader
This filter loads known inband metadata as packet properties. 👑
No options
wcdec
Description
WebCodec decoder
This filter decodes video streams using the WebCodec decoder of the browser. 🌈
Options (expert) ✨
queued(uint, default:10) — maximum number of packets to queue in webcodec instance
wcenc
Description
WebCodec encoder
This filter encodes video streams using the WebCodec encoder of the browser. ⭐
Options (expert) ✨
c(str) — codec identifier. Can be any supported GPAC codec name or ffmpeg codec name — updated to ffmpeg codec name after initializationfintra(frac, default:-1/1) — force intra / IDR frames at the given period in sec, e.g.fintra=2will force an intra every 2 seconds andfintra=1001/1000will force an intra every 30 frames on30000/1001=29.97fps video; ignored for audioall_intra(bool, default:false, updatable) — only produce intra framesb(uint, default:0) — bitrate in bits per seconds, defaults to 2M for video and 124K for audioqueued(uint, default:10) — maximum number of packets to queue in webcodec instance
webgrab
Description
Web-based AV capture
This filter grabs audio and video streams MediaStreamTrackProcessor of the browser. 🎥
Supported URL schemes:
video://grabs from cameraaudio://grabs from microphoneav://grabs both audio from microphone and video from cameravideo://ELTIDgrabs from DOM element with ID ELTID (the element must be a valid element accepted by VideoFrame constructor)
Options (expert) ✨
src(str) — source urlvsize(v2di, default:0x0) — desired webcam resolutionback(bool, default:false) — use back camerantp(bool, default:false) — mark packets with NTPalpha(bool, default:false) — keep alpha when grabbing canvasfps(frac, default:0/1) — framerate to use when grabbing images —0FPS means single image
dtout
Description
DekTec SDI output
This filter provides SDI output to be used with DTA 2174 or DTA 2154 cards. 📺
Options (expert) ✨
bus(sint, default:-1) — PCI bus number. If not set, device discovery is usedslot(sint, default:-1) — PCI bus number. If not set, device discovery is usedfps(frac, default:30/1) — default FPS to use if input stream fps cannot be detectedclip(bool, default:false) — clip YUV data to valid SDI range, slowerport(uint, default:1) — set sdi output port of cardstart(dbl, default:0.0) — set playback start offset,[-1, 0]means percent of media dur, e.g.-1 == dur
ohevcdec
Description
OpenHEVC decoder
This filter decodes HEVC and LHVC (HEVC scalable extensions) from one or more PIDs through the OpenHEVC library. 🔥
Options (expert) ✨
threading(enum, default:frame) — set threading modeframeslice: parallel decoding of both frames and slicesframe: parallel decoding of framesslice: parallel decoding of slices
nb_threads(uint, default:0) — set number of threads (if0, uses number of cores minus one)no_copy(bool, default:false) — directly dispatch internal decoded frame without copypack_hfr(bool, default:false) — pack 4 consecutive frames in a single outputseek_reset(bool, default:false) — reset decoder when seekingforce_stereo(bool, default:true) — use stereo output for multiview (top-bottom only)reset_switch(bool, default:false) — reset decoder at config change
uncvg
Description
Uncompressed Video Generator
Version: 1.0
Author: GPAC team - (c) Telecom ParisTech 2023 - license LGPL v2
This filter provides generation of test images for ISO/IEC 23001-17. 🎨
Generated pixels can be:
- a pattern of colors in columns, or in rectangles if
sqis set, using the specified palette. - an image source if
imgis used.
Colors specified in the palette can be default GPAC colors (see gpac -h colors), 0xRRGGBB or 0xAARRGGBB.
When generating video, the pixels are shifted to the left at every frame. ✨
Components are described as N[bpc][+k] with:
N: component type, one ofM(mono),Y,U,V,R,G,B,A,d(depth),disp,p(palette),f(filterArray),x(pad)bpc: bits per component value, default is8. Non-integer values must be one ofsft: floating-point value on 16 bitsflt: floating-point value on 32 bitsdbl: floating-point value on 64 bitsdblx: floating-point value on 128 bitscps: complex value as two floats on 16 bits eachcpf: complex value as two floats on 32 bits eachcpd: complex value as two floats on 64 bits eachcpx: complex value as two floats on 128 bits each
k: force component alignment on k bytes, default is0(no alignment)vsize(v2d, default:128x128) — width and height of the output imagec(strl, default:R8,G8,B8) — image componentstiles(v2d, default:1x1) — how many horizontal and vertical tiles you wantinterleave(enum, default:pix) — the interleave type, choose your fightercomp— component-based interleaving (planar modes)pix— pixel-based interleaving (packed modes)mix— pixel-based interleaving for UV (semi-planar modes)row— row-based interleavingtile— tile-component interleavingmulti— pixel-based interleaving (packed modes) for sub-sampled modes
sampling(enum, default:none) — sampling typesnone— no sub-sampling422— YUV 4:2:2 sub-sampling420— YUV 4:2:0 sub-sampling411— YUV 4:1:1 sub-sampling
block_size(uint, default:0) — block size in bytespad_lsb(bool, default:false) — padded bits are at LSB in the blockble(bool, default:false) — block is little endianbr(bool, default:false) — block has reversed componentspixel_size(uint, default:0) — size of a pixel in bytesrow_align(uint, default:0) — row alignment in bytestile_align(uint, default:0) — tile alignment in bytescle(bool, default:false) — byte-aligned components are little endianimg(str, default: empty) — use the specified image as input instead of generating RGBasize(bool, default:false) — use the input image sizepal(strl, default:red,green,blue,white,black,yellow,cyan,grey,orange,violet) — the default palette for color generationfa(strl, default:B,G,G,R) — bayer-like filter, and heads up: only 2x2 on R,G,B components is supportedbpm(strl, default: empty) — set the sensor bad pixel map as a list ofcN(broken column),rM(broken row) orNxM(single pixel)fps(frac, default:25/1) — frame rate to generate, and using0will trigger item muxingdur(frac, default:1/1) — duration to generate, and using0will trigger item muxingcloc(uint, default:-1, minmax:-1,6) — set the chroma location typestereo(bool, default:false) — dump a stereo imagesq(flt, default:0) — generate square patterns instead of columnsshade(bool, default:false) — shade pixels from black at the bottom to full intensity at the topscpt(bool, default:false) — use a single color per tile, with the first tile using the first color in the palette
glpush
Description: GPU texture uploader Version: 1.0 Author: GPAC team
Bestie this one literally shoves your input video streams onto the GPU as OpenGL textures 💅 you can use it to simulate hardware decoders dispatching OpenGL textures.
No options — that's it, that's the whole filter, no flags, no knobs, iconic behavior honestly.
thumbs
Description: Thumbnail generator Version: 1.0 Author: GPAC team
Okay so this filter makes screenshots out of a video stream 🎀
Your input video gets down-sampled by the scale factor. The output size is configured based on how many images per line and per column you put in the grid. And once it's configured, the output size is no longer modified — it's locked in, periodt.
The snap option says "use one video frame every however many seconds." If the value is 0, then literally every single input frame gets used.
If the number of rows is 0, it'll be computed based on the source duration and your desired snap time, and it defaults to 10 if it can't be resolved.
Want one image per input frame? Use :grid=1x1. Easy.
If you're doing a single image per output frame, the default for snap is 0 and the default for scale is 1. Otherwise (the multi-image vibe), the default for snap is 1 second and scale is 10.
A single line of text can be inserted over each frame ✨ and you can use predefined keywords in your input text, written as $KEYWORD$:
ts— replaced by packet timestamptimescale— replaced by PID timescaletime— replaced by packet time asHH:MM:SS.mscpu— replaced by current CPU usage of processmem— replaced by current memory usage of processversion— replaced by GPAC versionfversion— replaced by GPAC full versionmae— replaced by Mean Absolute Error with previous framemse— replaced by Mean Square Error with previous frameP4CC,PropName— replaced by corresponding PID property
Example
gpac -i src reframer:saps=1 thumbs:snap=30:grid=6x30 -o dump/$num$.png
This will generate images from key-frames only, inserting one image every 30 seconds. Using key-frame filtering is much faster but may give unexpected results if there are not enough key-frames in the source 👀
Example
gpac -i src thumbs:snap=0:grid=5x5 -o dump/$num$.png
This will generate one image containing 25 frames every second at 25 fps 🔥
If a single image per output frame is used and the scaling factor is 1, the input packet is reused as input with text and graphics overlaid.
Example
gpac -i src thumbs:grid=1x1:txt='Frame $time$' -o dump/$num$.png
This will inject text over each frame and keep timing and other packet properties 🫶
A json output can be specified in the input list to let applications retrieve the frame position in the output image from its timing.
Scene change detection
The filter can compute the absolute and/or square error metrics between consecutive images and drop an image if the computed metric is less than the given threshold.
If both mae and mse thresholds are 0, scene detection is not performed (that's the default). If both mae and mse thresholds are not 0, the frame is added if it passes both thresholds.
For both metrics: a value of 0 means all pixels are the same, and a value of 100 means all pixels have 100% intensity difference (e.g. black versus white).
The scene detection is performed after the snap filtering and uses:
- the previous frame in the stream, whether it was added or not, if
screfis not set, - the last added frame otherwise.
Typical thresholds for scene cut detection are 14 to 20 for mae and 5 to 7 for mse.
Since this is a costly process, it's recommended to use it combined with key-frames selection:
Example
gpac -i src reframer:saps=1 thumbs:mae=15 -o dump/$num$.png
The maxsnap option can be used to force insertion after the given time if no scene cut is found.
Options (expert):
grid(v2di, default:6x0) — number of images per lines and columnsscale(dbl, default:-1) — scale factor for input sizemae(uint, default:0, minmax:0,100) — scene diff threshold using Mean Absolute Errormse(uint, default:0, minmax:0,100) — scene diff threshold using Mean Square Errorlw(dbl, default:0.0) — line width between images in pixelslc(str, default:white) — line colorclear(str, default:white) — clear colorsnap(dbl, default:-1) — duration between images,0for all imagesmaxsnap(dbl, default:-1) — maximum duration between two thumbnails when scene change detection is enabledpfmt(pfmt, default:rgb) — output pixel formattxt(str, default: empty) — text to insert per thumbnailtc(str, default:white) — text colortb(str, default:black) — text shadowfont(str, default:SANS) — font to usefs(dbl, default:10) — font size to use in percent of scaled heighttv(dbl, default:0) — text vertical position in percent of scaled heightthread(sint, default:-1) — number of threads for software rasterizer,-1for all available coresblt(bool, default:true) — use blit instead of software rasterizerscref(bool, default:false) — use last inserted image as reference for scene change detectiondropfirst(bool, default:false) — drop first imagelist(str, default:null) — export json list of frame times and positions to given filelxy(bool, default:false) — add explicit x and y in json export
txtgen
Description: Text Generator Version: 1.0 Author: GPAC Team
This filter generates text streams based on the provided src file. By default, the filter uses a lorem ipsum text file 🌸
The type parameter sets the text generation mode. If it's set to 'txt', the filter generates text based on the source file.
If it's set to 'utc', the filter generates text based on the current UTC time. If it's set to 'ntp', the filter generates text based on the current NTP time.
When the unit is set to 'w', the filter generates text based on words. When it's set to 'l', the filter generates text based on lines.
The fdur parameter sets the frame duration of the text stream. Total duration of the text stream is set by the dur parameter. And if it's set to 0/0, the text stream will be infinite ♾️
The rollup parameter enables roll-up mode up to the specified number of lines. In roll-up mode, the filter accumulates text until the specified number of lines is reached.
When the number of lines is reached, the filter removes the first line and continues accumulating text.
You'd use rollup in combination with unit set to 'l' to create a roll-up subtitle effect. Or set unit to 'w' to create a roll-up text effect ✨
The lmax parameter sets the maximum number of characters in a line. If the line in the source file is longer than this, the excess text will be wrapped. 0 means no limit.
When rt is set to true, the filter generates text in real-time. If it's set to false, the filter generates text as fast as possible ⚡
Options (expert):
src(str, default:/usr/local/share/gpac/scripts/jsf/txtgen/lipsum.txt) — source of text. If not set, the filter will use lorem ipsum texttype(enum, default:txt) — type of text to generatetxt— plain text (usessrcoption)utc— UTC timentp— NTP time
unit(enum, default:l) — minimum unit of text from the sourcew— wordl— line
fdur(frac, default:1/1) — duration of each framelmax(uint, default:32) — maximum number of characters in a line. If the line in the source file is longer than this, the excess text will be wrapped.0means no limitdur(frac, default:0/0) — duration of the text streamrollup(uint, default:0) — enable roll-up mode up to the specified number of lineslock(bool, default:false) — lock timing to text generationrt(bool, default:true) — real-time mode
✨ mediaserver ✨
Description: Media Server Version: 1.0 Author: GPAC team - (c) Telecom Paris 2024 - license LGPL v2
Okay bestie, gather round, because this filter is literally an HTTP server AND a proxy for GET and HEAD requests, and it supports Multicast ABR sources. 💅 iconic behavior.
This filter does not produce PIDs — instead it attaches to an HTTP output filter. And if no HTTP output filter is specified in the session, bestie, the filter will just create one itself. main character energy fr. 👑
The file .gpac_auth, if it's present in the current working directory, will be used for authentication — unless --rdirs is set. 👀
If more options need to be specified for the HTTP output filter, they can be passed as local options or using global options:
gpac mediaserver:cors=on --user_agent=MyUser
Although it's not recommended, a server may be specified explicitly:
gpac mediaserver httpout:OPTS
In this case, the first httpout filter created will be used.
Also heads up: default request handling of httpout filter through read / write directories is disabled. 🚫
🎀 Services Configuration 🎀
The service configuration is set using scfg. It shall be a JSON file containing a single array of services. Each service is a JSON object with one or more of the following properties:
id— (string, defaultnull) Service identifier used for logsactive— (boolean, defaulttrue) service is ignored iffalsehttp— (string, defaultnull) URL of remote service to proxy (either resource name or server path)gcache— (boolean, defaultfalse) use gpac local disk cache when fetching media from HTTP for this servicelocal— (string, defaultnull) local mount point of this servicekeepalive— (number, default4) remove the service if no request received for the indicated delay in seconds (0force service to stay in memory forever)mabr— (string, defaultnull) address of multicast ABR source for this servicetimeshift— (number, default10) time in seconds a cached file remains in memoryunload— (number, default4) multicast unload policyactivate— (number, default1) multicast activation policymcache— (boolean, defaultfalse) cache manifest filesrepair— (string, defaultfalse) enable unicast repair in MABR stackfalse: disable repairtrue: enable repair using source URL or repair servers indicated in MABRauto: enable repair only from repair servers indicated in MABR
corrupted— (boolean, defaultfalse) forward corrupted files if parsable (valid container syntax, broken media)check_ip— (boolean, , defaultfalse) monitor IP address and port rather than connection when tracking active clientsnoproxy— (boolean) disable proxy for service when local mount point is set. Default istrueif bothlocalandhttpare set,falseotherwisesources— (array, defaultnull) list of sources objects for file-only services. Each source has the following property:name: name as used in resource path,url: local or remote URL to use for this resource.
js— (string, defaultnull) built-in or custom request resolver
Any JSON object with the property comment set will be ignored. 🙈
Not all properties are used for each type of service, and other properties can be defined by custom request resolvers. ✨
🦋 Proxy versus Server 🦋
All services using the http option can be exposed by the server without exposing the origin URL, rather than being proxied. To enable this, the local service configuration option must be set to:
- the exposed server path, in which case manifest names are not rewritten
- or the exposed manifest path, in which case manifest names are rewritten, but only one manifest can be exposed (does not work with dual MPD and M3U8 services)
Example
{ "http": "https://test.com/live/dash/live.mpd", "local": "/service1/"}
The server will translate any request /service1/foo/bar.ext into https://test.com/live/dash/foo/bar.ext.
Example
{ "http": "https://test.com/live/dash/live.mpd", "local": "/service1/manifest.mpd"}
The server will translate:
- request
/service1/manifest.mpdintohttps://test.com/live/dash/live.mpd - any request
/service1/foo/bar.extintohttps://test.com/live/dash/foo/bar.ext
Note: The URL must point to a self-contained subdirectory of the remote site. Any URLs outside this directory will either fail or be resolved as absolute path on the remote site.
When local is not set, these services are always acting as proxies for the http URL.
When noproxy is explicitly set to false for the services with both http and local, the remote URL will be available as a proxy service as well. 🫶
💖 HTTP Proxy and Relay 💖
The server can act as a proxy for HTTP requests — either for any requests, or by domain or resource name. 😌 so versatile.
Service configuration parameters used : http (mandatory), gcache, local.
Configuration for activating proxy for a specific network path:
{ "http": "https://test.com/video/"}
Configuration for activating proxy for any network path:
{ "http": "*"}
Configuration for a relay on a given path:
{ "http": "https://test.com/some/path/to/video/", "local": "/myvids/"}
This will resolve any request http://localhost/myvids/* to https://test.com/some/path/to/video/*
Note: The requests are never cached in memory in this mode, but can be cached on disk if gcache is set.
🌸 HTTP Streaming Cache 🌸
The server can act as a cache for live HTTP streaming sessions. The live edge can be cached in memory for a given duration. periodt. 💅
Service configuration parameters used : http ( mandatory), timeshift, mcache, gcache, keepalive and local.
Configuration for proxying while caching a live HTTP streaming service:
{ "http": "https://test.com/dash/live.mpd", "timeshift": 30 }
Configuration for relay caching a live HTTP streaming service:
{ "http": "https://test.com/dash/live.mpd", "timeshift": 30, "local": "/myservice/test.mpd"}
The local service configuration option can be set to:
- the exposed server path, in which case manifest names are not rewritten
- or the exposed manifest path, in which case manifest names are rewritten, but only one manifest can be exposed (does not work with dual MPD and M3U8 services)
👑 Multicast ABR Gateway 👑
The server can be configured to use a multicast ABR source for an HTTP streaming service, without any HTTP source. the way that is possible?? 😭 iconic.
Service configuration parameters used : mabr (mandatory), local (mandatory), corrupted, timeshift and keepalive.
The multicast source can be DVB-MABR (e.g. mabr://235.0.0.1:1234/), ATSC3.0 (e.g. atsc://) or ROUTE (e.g. route://235.0.0.1:1234/).
- If the multicast is replayed from a file, netcap ID shall be set in this multicast URL (e.g.
:NCID=N). - If a specific IP interface is used, it can also be set in multicast URL (e.g.
:ifce=IP).
For example, with local set to /service/live.mpd with mabr set, the server will expose the multicast service as http://localhost/service/live.mpd.
The manifest name can be omitted, in which case the exact manifest name used in the broadcast shall be used (and known to the client).
Configuration for exposing a MABR session:
{ "mabr": "mabr://234.0.0.1:1234", "local": "/service1", "timeshift": 30 }
💫 Multicast ABR Gateway with HTTP cache 💫
Okay so bestie, plot twist: the server can be set up to use a multicast source as an alternate data source for a given HTTP streaming service. Iconic.
Service configuration parameters used: http (mandatory), mabr (mandatory), local, corrupted, timeshift, repair, gcache, mcache, unload, activate, keepalive and js.
The multicast service can be dynamically loaded at run-time using the unload service configuration option:
- if
0, the multicast is started when loading the server and never ended, - otherwise, the multicast is started dynamically and ended
unloadseconds after last deactivation.
The qualities in the multicast service can be dynamically activated or deactivated using the activate service configuration option:
- if
0, multicast streams are never deactivated, - otherwise, a multicast representation is activated only if at least
activateclients are consuming it, and deactivated otherwise.
The multicast service can use repair options of the MABR stack using the repair service configuration option:
- if
false, the file will not be sent until completely received (this increases latency), - otherwise, file data will be pushed as soon as available in order (after reception or repair).
If the corrupted option is set together with repair, HTTP-based repair is disabled and corrupted files are patched using the repair=strict mode of the routein filter. If files are completely lost, they will be fetched from httpsource.
⚠️ Warning: This may likely result in decoding/buffering pipeline errors and could fail with some players expecting no timeline holes (such as browsers). GPAC supports this. 💀
The number of active clients on a given quality is computed using the client connection state: any disconnect/reconnect from a client for the same quality will trigger a deactivate+activate sequence. If check_ip is set to true, the remote IP address+port are used instead of the connection. This however assumes that each client has a unique IP/port which may not always be true (NATs). 🙈
If timeshift is 0 for the service, multicast segments will be trashed as soon as not in use (potentially before the client request).
Note: Manifest files coming from multicast are currently never cached.
Configuration for caching a live HTTP streaming service with MABR backup:
{ "http": "https://test.com/dash/live.mpd", "mabr": "mabr://234.0.0.1:1234", "timeshift": 30}
For such services, the custom HTTP header X-From-MABR is defined:
- for client request, a value of
nowill disable MABR cache for this request; if absent or value isyes, MABR cache will be used if available - for client response, a value of
yesindicates the content comes from the MABR cache; if absent or value isnooroff-edge, the content comes from HTTP (off-edgeindicates a request outside of the timeshift buffer)
The dedicated root endpoint /stats returns, the response content type's count (yes, no, off-edge) served by the gateway. ✨
The js option can be set to a JS module exporting the following functions:
init: (mandatory) The function is called once at the start of the server. Parameters:scfg: the service configuration object- return value: must be
trueif configuration and initialization are successful,falseotherwise.
service_activation: (optional) The function is called when the service is activated or deactivated. Parameters:do_activate(boolean): iftrue, service is being loaded otherwise it is being unloaded- return value: none
quality_activation: (optional) The function is called when the given quality is to be activated or deactivated. If not present, (de)activation always happens. Parameters (in order):do_activate(boolean): iftrue, quality is being activated otherwise it is being deactivatedservice_id(integer): ID of the service as announced in the multicastperiod_id(string): ID of the DASH Period, ignored (empty) for HLSadaptationSet_ID(integer): ID of the DASH AdaptationSet, ignored (-1) for HLSrepresentation_ID(string): ID of the DASH representation or name of the HLS variant playlist- return value: shall be
trueif activation/deactivation shall proceed andfalseif activation/deactivation shall be canceled.
get_mcast_address: (optional) The function is called when the service is activated. Parameters:service_url(string): URL of service for which the multicast adress is queried- return value: shall be the multicast address to use for the service or
nullif no multicast is used (active multicast wil then be deactivated).
📁 File Services 📁
A file system directory can be exposed as a service. The way that it just... serves a folder. Obsessed.
Service configuration parameters used: local (mandatory), sources (mandatory), gcache and keepalive.
The local service configuration option must be set to the desired service path, and the sources service configuration option must one or more valid sources. Each source is either a file, a directory or a remote URL.
Configuration for exposing a directory:
{ "local": "/dserv/", "sources": [ { "name": "foo/", "url": "my_dir/" } ] }
This service will expose the content of directory my_dir/* as http://localhost/dserv/foo/*.
In this mode, file serving is handled directly by httpout filter and no memory caching is used. If the source is a remote HTTP one, the gcache option will indicate if GPAC local cache shall be used. 🦋
🧚 Module development 🧚
A JS module can be specified using the js option in the service configuration. The module export functions are:
init (mandatory)
- The function is called once at the start of the server
- Parameter: the service configuration object
- return value must be
trueif configuration and initialization are successful,falseotherwise
resolve (mandatory)
- Parameter: an HTTP request object from GPAC
The function returns an array of two values [result, delay]:
result:nullif error, a resolved string indicating either a local file or the reply body, or an objectdelay: iftrue, the reply is being delayed by the module for later processing
When an object is returned, the request is handled by the JS module in charge of sending the reply and reading the data. The object shall have the following properties:
read: same semantics as the request read methodon_close: optional function called when the request is closed
👑 Built-in modules 👑
🌈 Source Remultiplexer 🌈
Module is loaded when using js=remux.
This module remultiplexes the source files in a desired format without transcoding. No re-encoding, we're just shuffling the boxes around, periodt. 💅
Service configuration parameters used : local (mandatory), sources (mandatory).
Service configuration additional parameters:
fmt: default format to use (default ismp4). Supported formats are:src: no remultiplexingmp4: fragmented MP4ts: MPEG-2 TSgsf: GPAC streaming formatdash: MPEG-DASH format, single qualityhls: HLS format, single quality
Sources are described using the sources array in the service configuration.
CGI parameters for request are:
fmt: (string, same as service configurationfmt) multiplexing format. If set tosrc, all other CGI parameters are ignored.start: (number, default0) start time in second of re-multiplexed content.speed: (number, default1) speed (>=0), keep video stream only and remove non SAP frames.media: (string, defaultav) media filtering type'av': keep both audio and video'a': keep only audio'v': keep only video
Configuration for serving a directory with remultiplexing to mp4:
{"local": "/service1/", "js": "remux", "sources": [{"name": "vids", "url": "/path/to/vids/"}], "fmt": "mp4"}
✨ Options (expert): ✨
scfg(str) — service configuration filequit(bool, default:false) — exit server once last service has been deactivated
🎬 avmix 🎬
Description: Audio Video mixer Author: GPAC team
AVMix is an audio video mixer controlled by an updatable JSON playlist format. The filter can be used to:
- schedule video sequence(s) over time
- mix videos together
- layout of multiple videos
- overlay images, text and graphics over source videos
All input streams are decoded prior to entering the mixer.
- audio streams are mixed in software
- video streams are composed according to the
gpuoption - other stream types are not yet supported
OpenGL hardware acceleration can be used, but the supported feature set is currently not the same with or without GPU.
In software mode, the mixer will detect whether any of the currently active video sources can be used as a base canvas for the output to save processing time. The default behavior is to do this detection only at the first generated frame, use dynpfmt to modify this.
The filter can be extended through JavaScript modules. Currently only scenes and transition effects use this feature. 🫶
🌸 Live vs offline 🌸
When operating offline, the mixer will wait for video frames to be ready for 10 times lwait. After this timeout, the filter will abort if no input is available. This implies that there shall always be a media to compose, i.e. no "holes" in the timeline. Note: The playlist is still refreshed in offline mode.
When operating live, the mixer will initially wait for video frames to be ready for lwait seconds. After this initial timeout, the output frames will indicate:
- 'No signal' if no input is available (no source frames) or no scene is defined
- 'Signal lost' if no new input data has been received for
lwaiton a source
🎀 Playlist Format 🎀
Overview
The main components in a playlist are:
- Media sources and sequences: each source is described by one or more URL to the media data, and each sequence is a set of sources to be played continuously
- Transitions: sources in a sequence can be combined using transitions
- Scenes: a scene describes one graphical object to put on screen and if and how input video are mapped on objects
- Groups: a group is a hierarchy of scenes and groups with positioning properties, and can also be used to create offscreen images reused by other elements
- Timers: a timer can be used to animate scene parameters in various fashions
The playlist content shall be either a single JSON object or an array of JSON objects, hereafter called root objects. Root objects types can be indicated through a type property:
seq: a sequence objecturl: a source object (if used as root, a default sequence object will be created)scene: a scene objectgroup: a group objecttimer: a timer objectscript: a script objectconfig: a config objectwatch: a watcher objectstyle: a style object
Except for style, the type property of root objects is usually not even needed — the parser just guesses the object types from its properties. it's giving psychic 🔮
A root object with a property skip set to anything but 0 or false is ignored. And within a group hierarchy, any scene or group object with skip set to anything but 0 or false? Also ignored. skip = blocked, periodt 💅
Any unrecognized property that does not start with _ gets reported as a warning. So if you typo a property name, the terminal will call you out. ngl it's doing you a favor 🫶
Colors 🌈
Colors are handled as strings, formatted like this:
- the DOM color name (peep
gpac -h colorsfor the whole roster) ✨ - HTML codes
$RRGGBBor#RRGGBB - RGB hex values
0xRRGGBB - RGBA hex values
0xAARRGGBB - the color
noneis0x00000000, and what that actually means depends on the object using it (mysterious! iconic!)
If your JS code needs to mess with colors, use sys.color_lerp and sys.color_component. those are the ones, bestie 🎀
JS Hooks 🪝
Some object types let you run custom JS code. custom code?? in MY playlist?? yes. The script code can either be the value of the property, or live in a file that the property points to.
The code gets turned into a function (i.e. new Function(args, js_code)) when the playlist is first parsed or reloaded — from here on out we call that a JSFun. The JSFun's arguments and return value depend on the parent object type. The parent object is exposed as this inside JSFun, and you can absolutely use it to stash context info for your JS code. this is the way 💖
Your code can use the global functions and modules that are defined, especially:
sys: GPAC system moduleevg: GPAC EVG moduleos: QuickJS OS modulevideo_playing: video playing stateaudio_playing: audio playing statevideo_time: output video timevideo_timescale: output video timescalevideo_width: output video widthvideo_height: output video heightaudio_time: output audio timeaudio_timescale: output audio timescalesamplerate: output audio sampleratechannels: output audio channelscurrent_utc_clock: current UTC clock in msget_media_time: gets media time of output (no argument) or of the source with id matching the first argument. Returns:-4: not found-3: not playing-2: in prefetch-1: timing not yet known- value: media time in seconds (float)
resolve_url: resolves the URL given in the first argument against the media playlist URL and returns the resolved url (string)get_scene(id): gets scene with given IDget_group(id): gets group with given IDmouse_over(evt): returns the scene under the mouse described by a GPAC event, ornullif no scene (picking for scenes with perspective projection is not supported)mouse_over(x, y): returns the scene under coordinates{x, y}in pixels, where{0,0}is the center of the frame, the x axis points right and the y axis points up math class but make it cute
Scene and group options have to be accessed through getters and setters, no shortcuts:
scene.get(prop_name): gets the scene optionscene.set(prop_name, value): sets the scene optiongroup.get(prop_name): gets the group optiongroup.set(prop_name, value): sets the group option
Warning: results are undefined if your JS code modifies the scene/group objects in any other way. do NOT freestyle this one bestie 💀
Other playlist objects (and scene and group objects too) can be queried with query_element(ID, propName) or modified with update_element(ID, propName, value) (peep the playlist update section below).
Warning: there is no protection of global variables and state — write your script carefully! no safety net, no vibes check, just you 😭
On top of all that, scripts running inside scene modules can modify the internal playlist with:
remove_element(ID): removes a scene, group, sequence, timer, script or watcher with the given ID from the playlistparse_element(JSON): parses a root playlist element and adds it to the current playlistparse_scene(JSON, parent): parses a scene and adds it to the parent group if notnull, or to the root otherwiseparse_group(JSON, parent): parses a group and adds it to the parent group if notnull, or to the root otherwisereload_playlist(JSON): parses a new playlist (an empty JSON array will reset the playlist). If the calling scene is no longer in the resulting scene tree, it will be added to the root of the scene tree
All of these playlist-related functions must be called inside the update() callback of the scene module. no calling them from the group chat at 3am 🌙
Sequences 🎬
Properties for sequence objects:
id(null): sequence identifierloop(0): number of loops for the sequence (0means no loop,-1will loop forever) INFINITE LOOP MODE 🔁start(0): sequence start time (see notes). If negative, the sequence is not activestop(0): sequence stop time (see notes). If less thanstart, the sequence will stop only when it's overtransition(null): a transition object to apply between sources of the sequenceseq([]): array of one or more source objects
Notes 📝
Media source timing does not depend on whether the media is being used by a scene or not — it's only governed by the sequence parameters. Which means: a sequence that no active scene is using will not be rendered. no video, no audio, nothing, ghosted fr 👻
The syntax for the start and stop fields is:
now: resolves to the current UTC clock in live mode, and to0for non-live mode- date: converted to UTC date in live mode, and to
0for non-live mode - N: converted to current utc clock (or
0for non-live mode) plus N seconds UTC - "N": converted to current utc clock (or
0for non-live mode) plus N seconds UTC
In 'live' mode, if start is set using a UTC date, the sequence will have a start range equal to MAX(current_UTC - start_in_UTC, 0). Some sources may be skipped to fulfill this condition. This lets different instances of the filter using the same playlist initialize media time in the same fashion. synced up, as they should be ✨
When reloading the playlist:
- if the sequence is active, the
startvalue is ignored - if the sequence was not started, the
startvalue is updated - if the sequence was over, the
startvalue is updated only if greater than the previous resolved UTC start time
Sources 🎥
Properties for source objects:
id(null): source identifier, used when reloading the playlistsrc([]): list of sourceURL describing the URLs to play. Multiple sources will be played in parallel multitasking queen 👑start(0.0): media start time in sourcestop(0.0): media stop time in source, ignored if less than or equal tostartmix(true): if true, apply sequence transition or mix effect ratio as audio volume. Otherwise volume is not modified by transitionsfade('inout'): indicates how audio should be faded at stream start/end:in: audio fade-in when playing first frameout: audio fade-out when playing last frameinout: both fade-in and fade-out are enabled- other: no audio fade
keep_alive(false): if using a dedicated gpac process for one or more input, relaunch the process(es) at source end if exit code is greater than2or if not responding afterrtimeoutseek(false): if true andkeep_aliveis active, adjuststartaccording to the time elapsed since source start when relaunching the process(es)prefetch(500): prefetch duration in ms (play before the start time of source),0for no prefetchhold(false): if media duration is known and media stop time is greater than media duration, activate no signal mode until the desired stop time is reached (disable transition), otherwise move to the next source at end of stream
Source Locations 📍
Properties for sourceURL objects:
id(null): source URL identifier, used when reloading the playlistin(null): input URL or filter chain to load as string. Words starting with-are ignored. The first entry must specify a source URL, and additional filters and links can be specified using@N[#LINKOPT]and@@N[#LINKOPT]syntax, as ingpacport(null): input port for source. Possible values are:pipe: launch a gpac process to play the source using GSF format over pipetcp,tcpu: launch a gpac process to play the source using GSF format over TCP socket (tcp) or unix domain TCP socket (tcpu)- not specified or empty string: loads source using the current process
- other: use the value as input filter declaration and launch
inas a dedicated process (e.g.in="ffmpeg ..." port="pipe://...")
opts(null): options for the gpac process instance when using a dedicated gpac process, ignored otherwisemedia('all'): filter input media by type —afor audio,vfor video,tfor text (several characters allowed, e.g.avorva),allaccepts all input mediaraw(true): indicates if the input port is decoded AV (true) or compressed AV (false) when using a dedicated gpac process, ignored otherwise
Notes 📝
The special URL scheme ipid:// can be used to locate an input pid by link directives.
Example 💫
in=ipid://#foo=bar
This will use pids having property foo with value bar, regardless of source filter ID.
Example 💫
in=ipid://TEST#foo=bar
This will use pids having property foo with value bar coming from the filter with ID TEST.
When using the ipid:// scheme, filter chains cannot be specified (in accepts a single argument) and port is ignored. The syntax for link directive is the same as in gpac. However, if a listed property is not found on the input pid, the matching will fail. no partial credit, sorry babe 😭
When launching a child process, the input filter is created first and the child process is launched afterwards. order matters, always has 🌸
Warning: when launching a child process directly (e.g.in="ffmpeg ..."), any relative URL used ininmust be relative to the current working directory. iykyk 🫶
✨ 2D and 3D transformation ✨
Common properties for group and scene objects — these are the shared ones, bestie, both groups AND scenes get them:
active(true) — is this object active or not? An inactive object will not be refreshed nor rendered 💤x(0) — horizontal translationy(0) — vertical translationcx(0) — horizontal coordinate of rotation centercy(0) — vertical coordinate of rotation centerunits('rel') — unit type forx,y,cx,cy,widthandheight. Possible values are:rel: units are expressed in percent of current reference (see below 👀)pix: units are expressed in pixels
rotation(0) — rotation angle of the scene in degreeshscale(1) — horizontal scaling factor to apply to the groupvscale(1) — vertical skewing factor to apply to the scenehskew(0) — horizontal skewing factor to apply to the scenevskew(0) — vertical skewing factor to apply to the scenezorder(0) — display order of the scene or of the offscreen group (ignored for regular groups)untransform(false) — if true, reset parent tree matrix to identity before computing matrixmxjs(null) — JS code for matrix evaluationz(0) — depth translationcz(0) — depth coordinate of rotation centerzscale(1) — depth scaling factor to apply to the grouporientation([0, 0, 1, 0]) — scale along the given orientation axis[x, y, z, angle]— see VRMLscaleOrientationaxis([0, 0, 1]) — rotation axisposition([0, 0, auto]) — camera locationtarget([0, 0, 0]) — point where the camera is lookingup([0, 1, 0]) — camera up vectorviewport([0, 0, 100, 100]) — viewport for camerafov(45) — field of view in degreesar(0) — camera aspect ratio,0means defaultznear(0) — near Z plane distance,0means defaultzfar(0) — far Z plane distance,0means default
🌈 Coordinate System 🌈
Every group or scene lives in its own little local coordinate system, and here's how it works, fr fr:
{0,0}represents the center- X values increase to the right ➡️
- Y values increase to the top ⬆️
- Z values increase towards the eye of a viewer (Z=X^Y) 👁️
The 2D local transformation matrix is computed as rotate(cx, cy, rotation) * hskew * vskew * scale(hscale, vscale) * translate(x, y).
The 3D local transformation matrix is computed as translate(x, y, z) * rotate(cx, cy, cz, rotation) * scale(hscale, vscale, zscale). Skewing is not supported for 3D, bestie, don't even try it 💀
The default unit system (rel) is relative to the current established reference space:
- by default, the reference space is
{output_width, output_height}, the origin{0,0}being the center of the output frame - any group with
reference=true,width>0andheight>0establishes a new reference space{group.width, group.height}
Inside a reference space R, relative coordinates are interpreted as follows:
- For horizontal coordinates,
0means center,-50means left edge (-R.width/2),50means right edge (+R.width/2). - For vertical coordinates,
0means center,-50means bottom edge (-R.height/2),50means top edge (+R.height/2). - For width,
100meansR.width. - For height,
100meansR.height. - For depth (
zandcz) coordinates, the value is a percent of the reference height (+R.height).
If width=height, the width is set to the computed height of the object. If height=width, the height is set to the computed width of the object. Iconic little symmetry moment ✨
For x property, the following special values are defined:
ywill set the value to the computedyof the object.-ywill set the value to the computed-yof the object.
For y property, the following special values are defined:
xwill set the value to the computedxof the object.-xwill set the value to the computed-xof the object.
Changing reference is typically needed when creating offscreen groups, so that children relative coordinates are resolved against the offscreen canvas size. 🎯
The selection between 2D and 3D is done automatically based on z, cz, axis and orientation values.
The default projection is:
- viewport is the entire output frame
- field of view is
PI/4and aspect ratio isoutput width/height zNearis0.1andzFaris10timesmaximum(output width, output height)- camera up direction is Y axis and camera distance is so that a rectangle facing the camera with
z=0and size equal to output size covers exactly the output frame. - depth buffer is disabled
The default projection can be changed by setting camera properties at group or scene level. When set on a group, all children of the group will use the given camera properties (camera parameters on children are ignored). 🎥
The viewport parameter is specified as an array [x, y, w, h], where:
x: horizontal coordinate of the viewport center, in group or scene units, or'y'to useyvalue, or'-y'to use-yvalue.y: vertical coordinate of the viewport center, in group or scene units, or'x'to usexvalue, or'-x'to use-xvalue.w: width of the viewport, in group or scene units, or'height'to usehvalue.h: height of the viewport, in group or scene units, or'width'to usewvalue.
🫧 z-ordering 🫧
zorder specifies the display order of the element in the offscreen canvas of the enclosing offscreen group, or on the output frame if no offscreen group in parent tree.
This order is independent of the parent group z-ordering. This allows moving objects of a group up and down the display stack without modifying the groups. the way that just works without you touching anything else >>> 💅
🧚 Coordinate modifications through JS 🧚
The JSFun specified in mxjs has a single parameter tr.
The tr parameter is an object containing the following variables that the code can modify:
x,y,z,cx,cy,cz,hscale,vscale,zscale,hskew,vskew,rotation,untransform,axis,orientation: these values are initialized to the current group values in local coordinate system unitsupdate: if set totrue, the object matrix will be recomputed at each frame even if no change in the group or scene parameters (always enforced totrueifuseis set)depth: for groups withuse, indicates the recursion level of the used element. A value of0indicates this is a direct render of the element, otherwise it is a render throughuse
The JSFun may return false to indicate that the scene should be considered as inactive. Any other return value (undefined or not false) will mark the scene as active. ✅
Example 🍓
"mxjs": "tr.rotation = (get_media_time() % 8) * 360 / 8;
tr.update=true;"
👑 Grouping 👑
Properties for group objects:
id(null) — group identifierscenes([]) — zero or more group or scene objects, cannot be animated or updatedopacity(1) — group opacityoffscreen('none') — set group in offscreen mode, cannot be animated or updated. An offscreen mode is not directly visible but can be used in some texture operations. Possible values are:none: regular groupmask: offscreen surface is alpha+greycolor: offscreen surface is alpha+colors or colors ifback_coloris setdual: same ascolorbut allows group to be displayed
scaler(1) — when opacity or offscreen rendering is used, offscreen canvas size is divided by this factor (>=1)back_color('none') — when opacity or offscreen rendering is used, fill offscreen canvas with the given color.width(-1) — when opacity or offscreen rendering is used, limit offscreen width to given value (see below)height(-1) — when opacity or offscreen rendering is used, limit offscreen height to given value (see below)use(null) — id of group or scene to re-useuse_depth(-1) — number of recursion allowed for the used element, negative means global max branch depth as indicated bymaxdepthreverse(false) — reversescenesorder before drawreference(false) — group is a reference space for relative coordinate of children nodes
Notes 📝
The maximum depth of a branch in the scene graph is maxdepth (traversing aborts after this limit). so don't go building an infinite tower of groups, bestie, it WILL cut you off
In offscreen mode, the bounds of the enclosed objects are computed to allocate the offscreen surface, unless width and height are both greater or equal to 0.
Enforcing offscreen size is useful when generating textures for later effects.
Offscreen rendering is always done in software. 💀
When enforcing scaler>1 on a group with opacity==1, offscreen rendering will be used and the scaler applied.
When enforcing width and height on a group with opacity<1, the display may be truncated if children objects are out of the offscreen canvas bounds. 🫣
🎀 Scenes 🎀
Properties for scene objects:
id(null) — scene identifierjs('shape') — scene type, either builtin (see below) or path to a JS module, cannot be animated or updatedsources([]) — list of identifiers of sequences or offscreen groups used by this scenewidth(-1) — width of the scene,-1means reference space widthheight(-1) — height of the scene,-1means reference space heightmix(null) — a transition object to apply if more than one source is set, ignored otherwisemix_ratio(-1) — mix ratio for transition effect,<=0means first source only,>=1means second source onlyvolume(1.0) — audio volume (0: silence,1: input volume), this value is not clamped by the mixer.fade('inout') — indicate how audio should be faded at scene activate/deactivate:in: audio fade-in when playing first frame after scene activationout: audio fade-out when playing last frame at scene activationinout: both fade-in and fade-out are enabledother: no audio fade
autoshow(true) — automatically deactivate scene when sequences set insourcesare not activenosig('lost') — enable no-signal message for scenes using sequences:no: disable messagelost: display message when signal is lostbefore: display message if source is not yet activeall: always display message if source is inactive
styles([]) — list of style IDs to use- any other property exposed by the underlying scene JS module.
Notes 📝
Inputs to a scene, whether sequence or offscreen group, must be declared prior to the scene itself. order matters, bestie, it's giving strict 💅
A default scene will be injected if none is found when initially loading the playlist. If you need to start with an empty output, use a scene with no sequence associated.
If a scene uses one or more sequences and autoshow is not set, the scene will be drawn with no sequence attached if all sequences are inactive (not yet started or over). 🦋
💫 Transitions and Mixing effects 💫
JSON syntax
Properties for transition objects, bestie — write these down:
id(null) — the transition identifiertype— the transition type, either a builtin (peep below 👀) or a path to a JS moduledur— transition duration. Transitions always end at source stop time. This one gets ignored if the transition is specified for a scene mix 💀fun(null) — JS code modifying the ratio effect- any other property exposed by the underlying transition module.
Notes
okay so math moment ✨ a sequence of two media with playback duration (as indicated in source) of D1 and D2, using a transition of duration DT, will give you a sequence lasting D1 + D2 - DT. periodt.
The JSFun that fun specifies takes one argument ratio and must return the recomputed ratio.
Example
"fun": "return ratio*ratio;"
⏰ Timers and animations ⏰
Properties for timer objects:
id(null) — id of the timerdur(0) — duration of the timer in secondsloop(false) — loops the timer whenstopis not setpause(false) — pause the timerstart(-1) — start time (see notes); a negative value means inactivestop(-1) — stop time (see notes); ignored if it's less thanstartkeys([]) — list of keys used for interpolation, an ordered list between0.0and1.0anims([]) — list of animation objects
Properties for animation objects:
values([]) — list of values to interpolate; there must be as many values as there are keyscolor(false) — says the values are color (as strings)angle(false) — says the interpolation factor is an angle in degrees, to convert to radians (interpolation ratio multiplied by PI and divided by 180) before interpolationmode('linear') — interpolation mode:linear: linear interpolation between the valuesdiscrete: do not interpolate- other: JS code modifying the interpolation ratio
postfun(null) — JS code modifying the interpolation resultend('freeze') — behavior at end of animation:freeze: keep last animated valuesrestore: restore targets to their initial values
targets([]) — list of strings indicating targets properties to modify. The syntax is:ID@option: modifies propertyoptionof the object with the givenIDID@option[IDX]: modifies the value at indexIDXof the array propertyoptionof the object with the givenID
Notes
Currently, only scene, group, transition and script objects can be modified through timers (see playlist updates).
The syntax for the start and stop fields is:
now: resolves to the current UTC clock in live mode, and to0for non-live mode- date: converted to a UTC date in live mode, and to
0for non-live mode N: converted to the UTC clock at init plusNseconds for timer objects (absolute offset from timeline init)"N": converted to the current UTC clock plusNseconds (relative offset from current time) withNa positive or negative number
The JSFun specified by mode has one input parameter interp, equal to the interpolation factor, and must return the new interpolation factor.
Example
"mode":"return interp*interp;"
The JSFun specified by postfun has two input parameters, res (the current interpolation result) and interp (the interpolation factor), and must return the new interpolated value.
Example
"postfun": "if (interp<0.5) return res*res; return res;"
📜 Scripts 📜
Properties for script objects:
id(null) — id of the scriptscript(null) — JavaScript code or path to a JavaScript file to execute; cannot be animated or updatedactive(true) — indicates if the script is active or not
Notes
Script objects let you read and write access to the playlist from script. Right now they can only be used to modify scenes and groups, and to activate/deactivate other scripts.
The JSFun function specified by fun has no input parameter. The return value (default 0) is the number of seconds (float) to wait until the next evaluation of the script.
Example
{ "script": "let s=get_scene('s1'); let rot = s.get('rotation'); rot += 10; s.set('rotation', rot); return 2;" }
This will change scene s1 rotation every 2 seconds. slay 🔥
👀 Watchers 👀
Properties for watcher objects:
id(null) — ID of the watcheractive(true) — indicates if the watcher is active or notwatch("") — the element watched, formatted asID@prop, withIDthe element ID andpropthe property name to watchtarget("") — the action for the watcher. Allowed syntaxes are:ID@prop,ID@prop[idx]: copy value to propertypropof the elementID(potentially at indexidxif specified for arrays)ID.fun_name: call functionfun_nameexported from scene moduleID, using three arguments['value', 'watchID', 'watchPropName'], no return value check- otherwise: the action must be JS code, and the resulting JSFun has one argument
valuecontaining the watched value, and no return value check
with(undefined) — for targets in the formID@prop, use this value instead of the watched value
Notes
A watcher can be used to monitor changes in an object in the playlist. Any object property that can be animated or updated can be monitored by a watcher. 👑
In addition, the following virtual properties (cannot be read or written) can be watched:
sequence.active: value is set totruewhen the sequence is activated, andfalsewhen deactivatedsource.active: value is set totruewhen source playback starts, andfalsewhen source playback stopstimer.active: value is set totruewhen the timer starts, andfalsewhen the timer stops
Only the active property can be animated or updated in a watcher.
Example
{"watch": "s1@rotation", "target": "s2@rotation"}
This will copy s1.rotation to s2.rotation.
Example
{"watch": "s1@rotation", "target": "get_scene('s2').set('rotation', -value);" }
This will copy the -1*s1.rotation to s2.rotation.
Watching UI events
Watchers can also be used to monitor GPAC user events by setting watch to:
- an event name to monitor, one of
keydown,keyup,mousemove,mouseup,mousedown,wheel,textInput eventsto monitor all events (including internal events).
For keyup and keydown events, the key code to watch may additionally be given in parenthesis, e.g. 'watch': 'keyup(T)'.
Note: User events are only sent if the output of the filter is consumed by the vout filter. no cap.
When event monitoring is used, the target must be a JavaScript callback (i.e. it cannot be ID@prop). The JavaScript function will be called with a single argument evt containing the GPAC event.
Example
{"watch": "mousemove", "target": "let s = mouse_over(evt); get_scene('s2').set('fill', (s && (s.id=='s1') ? 'white' : 'black' );"}
This will set s1 fill color to white if the mouse is over s2, and to black otherwise. it's giving hover effects 💅
🎀 Styles 🎀
Properties for style objects:
id(null) — ID of the styleforced(false) — always apply style even when no modifications- other — any property to share between scene
Notes
A style object lets scenes share the same values for a given set of properties. 🫶
If a scene property has the same name as a style property, the scene property is replaced by the style property. Styles only apply to scene properties as follows:
volume,fade,mix_ratiocan use style- all options defined by the scene module can use style
- transformation or other scene properties cannot use style
Properties of a style object can be animated or updated, but a style object cannot be watched.
Styles are applied to each associated scene in order of declaration, e.g. ['st1', 'st2'] and ['st2', 'st1'] will likely give different results.
If force is not set for a style, the style is only applied after being modified (load, animation, update); if a scene uses ['st1', 'st2'] and only st1 is modified (animation, update), st2 will only be applied once.
⚙️ Filter configuration ⚙️
The playlist may specify configuration options of the filter, using a root object of type 'config':
- property names are the same as the filter options
- property values are given in the native type, or as strings for fractions (format
N/D), vectors (formatWxH) or enums - each declared property overrides the filter option of the same name (whether default or set at filter creation)
A configuration object in the playlist is only parsed when initially loading the playlist, and ignored when reloading it.
The following additional properties are defined for testing:
reload_tests([]) — list of playlists to reloadreload_timeout(1.0) — timeout in seconds before playlist reloadreload_loop(0) — number of times to repeat the reload tests (not including the original playlist, which is not reloaded)
🔄 Playlist modification 🔄
The playlist file can be modified at any time. Objects are identified across playlist reloads through their id property. Objects that are not present after reloading a playlist are removed from the mixer. This implies that reloading a playlist will recreate most objects with no ID associated. lowkey chaotic but okay 💀
A sequence object modified between two reloads is refreshed, except for its start field if the sequence is active.
A source object shall have the same parent sequence between two reloads. Any modification on the object will only be taken into consideration when (re)loading the source.
A sourceURL object is not tracked for modification, only evaluated when activating the parent source object.
A scene or group object modified between two reloads is notified of each changed value.
A timer object modified between two reloads is shut down and restarted. Consequently, animation objects are not tracked between reloads.
A transition object may change between two reloads, but any modification on the object will only be taken into consideration when restarting the effect.
A script object modified between two reloads has its code re-evaluated.
A watcher object modified between two reloads has its watch source and code re-evaluated.
A style object is not tracked (all styles are reloaded when reloading a playlist).
🎬 Playlist example 🎬
The following is an example playlist using a sequence of two videos with a mix transition and an animated video area:
Example
[
{"id": "seq1", "loop": -1, "start": 0, "seq":
[
{ "id": "V1", "src": [{"in": "s1.mp4"}], "start": 60, "stop": 80},
{ "id": "V2", "src": [{"in": "s2.mp4"}], "stop": 100}
],
"transition": { "dur": 1, "type": "mix"}
},
{"id": "scene1", "sources": ["seq1"]},
{"start": 0, "dur": 10, "keys": [0, 1], "anims":
[
{"values": [50, 0], "targets": ["scene1@x", "scene1@y"]},
{"values": [0, 100], "targets": ["scene1@width", "scene1@height"]}
]
}
]
and that's the whole playlist vibe, bestie 💖
✨ Updates Format ✨
okay so bestie, you do not have to reload the entire playlist just to change a thing or two. You can send updates to modify it instead. Iconic behaviour honestly.
Updates are read from a separate file specified in updates, and it's inactive by default.
⚠️ Warning: the updates file is only read when modified AFTER the initialization of the filter. So don't be showing up with a file you already wrote, it is not getting read, no cap.
The updates file content shall be either a single JSON object or an array of JSON objects. The properties of these objects are:
skip— iftrueor1, ignores the update, otherwise apply itreplace— string identifying the target replacement. Syntax is:ID@name: indicate propertynameof element with givenIDto replaceID@name[idx]: indicate the index in the propertynameof element with givenIDto replace
with— replacement value, must be of the same type as the target value
An id property cannot be updated. That one's off limits, sorry babe.
The following playlist elements of a playlist can be updated:
- scene — all properties except
jsand read-only module properties - group — all properties except
scenesandoffscreen - sequence —
start,stop,loopandtransitionproperties - timer —
start,stop,loop,pauseanddurproperties - transition — all properties
- for sequence transitions: most of these properties will only be updated at next reload
- for active scene transitions: whether these changes are applied right away depend on the transition module
Example 💫
[
{"replace": "scene1@x", "with": 20},
{"replace": "seq1@start", "with": "now"}
]
🎬 Scene modules 🎬
Scene clear 🧼
This scene clears the canvas area covered by the scene with a given color.
The default clear color of the mixer is black.
The clear area is always axis-aligned in output frame, so when skew/rotation are present, the axis-aligned bounding box of the transformed scene area will be cleared. iykyk.
Options:
color('none') — clear color
Scene clip ✂️
This scene resets the canvas clipper or sets the canvas clipper to the scene area.
The clipper is always axis-aligned in output frame, so when skew/rotation are present, the axis-aligned bounding box of the transformed clipper will be used.
Clippers are handled through a stack, resetting the clipper pops the stack and restores previous clipper. And if a clipper is already defined when setting the clipper, the clipper set is the intersection of the two clippers.
Options:
reset(false) — if set, reset clipper otherwise set it to scene position and sizestack(true) — if false, clipper is set/reset independently of the clipper stack (no intersection, no push/pop of the stack)
Scene mask 🎭
This scene sets the canvas alpha mask mode.
The canvas alpha mask is always full screen.
In software mode, combining mask effect in record mode and reverse group drawing allows drawing front to back while writing pixels only once. efficiency queen 💅
Options:
mode('off') — if set, reset clipper otherwise set it to scene position and size- off — mask is disabled
- on — mask is enabled and cleared, further draw operations will take place on mask
- onkeep — mask is enabled but not cleared, further draw operations will take place on mask
- use — mask is enabled, further draw operations will be filtered by mask
- use_inv — mask is enabled, further draw operations will be filtered by 1-mask
- rec — mask is in record mode, further draw operations will be drawn on output and will set mask value to 0
Scene shape 🌸
This scene can be used to setup a shape, its outline and specify the fill and strike modes. Supported shapes include:
- a variety of rectangles, ellipse and other polygons
- custom paths specified from JS
- text
The color modes for shapes and outlines include:
- texturing using data from input media streams (shape fill only)
- texturing using local JPEG and PNG files (shape fill only)
- solid color
- linear and radial gradients
The default scene is optimized to fallback to fast blit when no transformations are used on a straight rectangle shape. lowkey genius.
All options can be updated at run time.
The module accepts 0, 1 or 2 sequences as input.
Color replacement operations can be specified for base scenes using source videos by specifying the replace option. The replacement source is:
- the image data if
imgis set, potentially altered using*_repoptions - otherwise a linear gradient if
fill=linearor a radial gradient iffill=radial(NOT supported in GPU mode, use an offscreen group for this)
⚠️ Warning: Color replacement operations cannot be used with transition or mix effects. Not a vibe, don't try it.
Text options 🔤
Text can be loaded from file if text[0] is an existing local file. By default all lines are loaded. The number of loaded lines can be specified using text[1] as follows:
0or not present: all lines are loadedN > 0: only keep the lastNlinesN < 0: only keep the firstNlines
Text loaded from file will be refreshed whenever the file is modified. it's giving self-updating ✨
Predefined keywords can be used in input text, identified as $KEYWORD$. The following keywords (case insensitive) are defined:
time— replaced by UTC dateltime— replaced by locale datedate— replaced by date (Y/M/D)ldate— replaced by locale date (Y/M/D)mtime— replaced by output media timemtime_SRC— replaced by media time of input sourceSRCcpu— replaced by current CPU usage of processmem— replaced by current memory usage of processversion— replaced by GPAC versionfversion— replaced by GPAC full versionP4CC, PropName— replaced by corresponding PID property
Custom paths 🛤️
Custom paths (shapes) can be created through JS code indicated in 'shape', either inline or through a file. The following GPAC JS modules are imported:
Sysassys- All EVG as
evg osform QuickJS
See https://doxygen.gpac.io for more information on EVG and Sys JS APIs.
The code is exposed the scene as this. The variable this.path is created, representing an empty path.
Example
"shape": "this.path.add_rectangle(0, 0, this.width, this.height); let el = new evg.Path().ellipse(0, 0, this.width, this.height/3); this.path.add_path(el);"
The default behaviour is to use the shape width and height as reference size for texture mapping. If your custom path is textured, with bounding rectangle size different from the indicated shape size, set the variable this.tx_adjust to true.
In the previous example, the texture mapping will not be impacted by the custom path size.
Example
"shape": "this.path.add_rectangle(0, 0, this.width, this.height); let el = new evg.Path().ellipse(0, 0, this.width, this.height/3); this.path.add_path(el); this.tx_adjust = true;"
In this example, the texture mapping will be adjusted to the desired size.
The global variables and functions are available (c.f. gpac -h avmix:global):
get_media_time()— return media time in seconds (float) of outputget_media_time(SRC)— get time of source with idSRC, return-4if not found,-3if not playing,-2if in prefetch,-1if timing not yet known, media time in seconds (float) otherwisecurrent_utc_clock— current UTC time in msvideo_time— output video timevideo_timescale— output video timescalevideo_width— output video widthvideo_height— output video height
If your path needs to be reevaluated on regular basis, set the value this.reload to the timeout to next reload, in milliseconds. 🦋
✨ Options
rx(0) — horizontal radius for the rounded rect, in percent of the object width if it's positive, in absolute value if it's negative; and if the value isy, bestie, it means usery💅ry(0) — vertical radius for the rounded rect, in percent of the object height if it's positive, in absolute value if it's negative; valuexmeans userxtl(1) — top-left corner scaler (positive,0disables the corner)bl(1) — bottom-left corner scaler (positive,0disables the corner)tr(1) — top-right corner scaler (positive,0disables the corner)br(1) — bottom-right corner scaler (positive,0disables the corner)rs(false) — repeat texture horizontallyrt(false) — repeat texture verticallykeep_ar(true) — keep aspect ratio, obviously 💖pad_color('0x00FFFFFF') — color to use for texture padding ifrsorrtare false. Usenoneto use the texture edge,0x00FFFFFFfor transparent (always enforced if the source is transparent)txmx([]) — texture matrix. All 6 coefficients must be set, i.e.[xx xy tx yx yy ty]cmx([]) — color transform. All 20 coefficients must be set in order, i.e.[Mrr, Mrg, Mrb, Mra, Tr, Mgr, Mgg ...]line_width(0) — line width in percent of width if positive, or absolute value if negativeline_color('white') — line color;linearfor linear gradient andradialfor radial gradientline_pos('center') — line/shape positioning. Possible values are:center: line is centered around shapeoutside: line is outside the shapeinside: line is inside the shape
line_dash('plain') — line dashing mode. Possible values are:plain: no dashdash: predefined dash pattern is useddot: predefined dot pattern is useddashdot: predefined dash-dot pattern is useddashdashdot: predefined dash-dash-dot pattern is useddashdotdot: predefined dash-dot-dot pattern is used
dashes([]) — dash/dot pattern lengths for custom dashes (these will be multiplied by line size)cap('flat') — line end style. Possible values are:flat: flat endround: round endsquare: square end (extends limit compared to flat)triangle: triangle end
join('miter') — line joint style. Possible values are:miter: miter join (straight lines)round: round joinbevel: bevel joinbevelmiter: bevel+miter join
miter_limit(2) — miter limit for joint stylesdash_length(-1) — length of path to outline, negative values mean full pathdash_offset(0) — offset in path at which the outline startsblit(true) — use blit if possible, otherwise EVG texturing. If disabled, always use texturingfill('none') — fill color if used without sources;linearfor linear gradient andradialfor radial gradientimg('') — image for scene without sources or whenreplaceis set. Accepts either a path to a local image (JPG or PNG), the ID of an offscreen group or the ID of a sequencealpha(1) — global texture transparencyreplace('') — ifimgorfillis set and the shape is using source, set multi texture option. Possible modes are:a,r,gorb: replace alpha source component by indicated component fromimg. If prefix-is set, replace by one minus the indicated componentm: mix usingmix_ratiothe color components of source andimgand set alpha to full opacityM: mix usingmix_ratioall components of source andimg, including alphaxC: mix source 1 and source 2 usingimgcomponentC(a,r,gorb) and force alpha to full opacityXC: mix source 1 and source 2 usingimgcomponentC(a,r,gorb), including alpha
shape('rect') — shape type. Possible values are:rect: rounded rectanglesquare: square using smaller width/height valueellipse: ellipsecircle: circle using smaller width/height valuerhombus: axis-aligned rhombustext: force text mode even if text field is emptyrects: same as rounded rectangle but use straight lines for corners- other value: JS code for custom path creation, either string or local file name (dynamic reload possible)
grad_p([]) — gradient positions between0and1grad_c([]) — gradient colors for each position, as stringsgrad_start([]) — start point for linear gradient or center point for radial gradientgrad_end([]) — end point for linear gradient or radius value for radial gradientgrad_focal([]) — focal point for radial gradientgrad_mode('pad') — gradient mode. Possible values are:pad: color padding outside of gradient boundsspread: mirror gradient outside of boundsrepeat: repeat gradient outside of bounds
text([]) — text lines (UTF-8 only). If not empty, forceshape=textfont([]) — font name(s)size(20) — font size in percent of height (horizontal text) or width (vertical text), or absolute value if negativebaseline('alphabetic') — baseline position. Possible values are:alphabetic: alphabetic position of baselinetop: baseline at top of EM Boxhanging: reserved, not implementedmiddle: baseline at middle of EM Boxideograph: reserved, not implementedbottom: baseline at bottom of EM Box
align('center') — horizontal text alignment. Possible values are:center: center of shapestart: start of shape (left or right depending on text direction)end: end of shape (right or left depending on text direction)left: left of shaperight: right of shape
spacing(0) — line spacing in percent of height (horizontal text) or width (vertical text), or absolute value if negativebold(false) — use bold version of fontitalic(false) — use italic version of fontunderline(false) — underline textvertical(false) — draw text verticallyflip(false) — flip text verticallyextend(0) — maximum text width in percent of width (for horizontal) or height (for vertical), or absolute value if negativekeep_ar_rep(true) — same askeep_arfor local image in replace modetxmx_rep([]) — same astxmxfor local image in replace modecmx_rep([]) — same ascmxfor local image in replace modepad_color_rep('none') — same aspad_colorfor local image in replace moders_rep(false) — same asrsfor local image in replace modert_rep(false) — same asrtfor local image in replace mode
🦋 Transition modules
💜 Transition fade — software/GPU
This transition performs fade to/from color of source videos 🎀
Options:
color('black') — fade color
🌸 Transition gltrans — GPU only
This transition module wraps gl-transitions, see https://gl-transitions.com/ and gpac -h avmix:gltrans for builtin transitions ✨
Options:
fx('') — effect name for built-in effects, or path to gl-transition GLSL file
🫶 Transition mix — software/GPU
This transition performs cross-fade of source videos, no cap 💅
👑 Transition swipe — software/GPU
This transition performs simple 2D affine transformations for source videos transitions, with configurable effect origin 🌈
Options:
from('left') — direction of video 2 entry. Possible values are:left: from left to right edgesright: from right to left edgestop: from top to bottom edgesbottom: from bottom to top edgestopleft: from top-left to bottom-right cornerstopright: from top-right to bottom-left cornersbottomleft: from bottom-left to top-right cornersbottomright: from bottom-right to top-left corners
mode('slide') — how video 2 entry impacts video 1. Possible values are:slide: video 1 position is not modifiedpush: video 2 pushes video 1 awaysqueeze: video 2 squeezes video 1 along opposite edgegrow: video 2 size increases, video 1 not modifiedswap: video 2 size increases, video 1 size decreases
✨ Options (expert) ✨
pl(str, default:avmix.json) — local playlist file to loadlive(bool, default:true) — live modegpu(enum, default:off) — enable GPU usageoff: no GPUmix: only render textured path to GPU, use software rasterizer for the outlines, solid fills and gradientsall: try to use GPU for everything
thread(sint, default:-1) — use threads for software rasterizer (-1for all available cores)lwait(uint, default:1000) — timeout in ms before considering no signal is presentltimeout(uint, default:4000) — timeout in ms before restarting child processesmaxdur(dbl, default:0) — run for given seconds and exit, will not abort if0(used for live mode tests)updates(str) — local JSON files for playlist updatesmaxdepth(uint, default:100) — maximum depth of a branch in the scene graphvsize(v2d, default:1920x1080) — output video size,0disable video outputfps(frac, default:25) — output video frame ratepfmt(pfmt, default:yuv) — output pixel format. Usergbain GPU mode to force alpha channeldynpfmt(enum, default:init) — allow dynamic change of output pixel format in software modeoff: pixel format is forced to desired valueinit: pixel format is forced to format of fullscreen input in first generated frameall: pixel format changes each time a full-screen input PID at same resolution is used
sr(uint, default:44100) — output audio sample rate,0disable audio outputch(uint, default:2) — number of output audio channels,0disable audio outputafmt(afmt, default:s16) — output audio format (onlys16,s32,fltanddblare supported)alen(uint, default:1024) — default number of samples per frame
💀 avgen 💀
Description: AV Counter Generator
Version: 1.0
Author: GPAC Team
This filter generates AV streams representing a counter, bestie. Streams can be enabled or disabled using type 🎀
The filter is software-based and does not use GPU. Okay so, no GPU glow-up here, it's just doing its thing 💅
When adjust is set, the first video frame is adjusted such that a full circle happens at each exact second according to the system UTC clock ⏰✨
By default, video UTC and date are computed at each frame generation from current clock and not from frame number.
This will result in broken UTC timing text when playing at speeds other than 1.0. 😭
This can be changed using lock.
Audio beep is generated every second, with octave (2xfreq) of even beep used every 10 seconds 🔊
When video is generated, beep is synchronized to video at each exact second.
If NTP injection is used, each video packet (but not audio ones) has a SenderNTP property set; if video is not used, each audio packet has a SenderNTP property set 🦋
🌈 Multiple output stream generation
okay so bestie, you're not limited to ONE output size. Want more? You got more. Slap down several sizes and you get multiple sources generated, one per size, periodt.
And here's the cute part: a size can be specified more than once. When you do that, you get packet references — unless copy is set, in which case you get full copies instead. iykyk.
Target encoding bitrates can be assigned to each output using rates. Genuinely so useful when you're generating dash:
gpac avgen:sizes=1280x720,1920x1080:rates=2M,5M c=aac:FID=1
c=264:FID=2:clone -o live.mpd:SID=1,2
🦋 Multiview generation
In multiview mode, the only thing that moves in depth — backward and forward — is the animated counter, and how much it moves is indicated by the disparity value. That's it. That's the whole vibe.
When pack is set, a packed stereo couple is generated for each video packet. Cute.
Otherwise — so when pack is NOT set — if views is greater than 2, each view gets generated on a dedicated output PID with the property ViewIdx set in [1, views].
heads up 💀 Multi-view output forces usage of copy mode. No negotiating.
💅 PID Naming
The naming rules, laid out for you:
- The audio PID is assigned the name
audioand ID1. - If a single video PID is produced, it's assigned the name
videoand ID2. - If multiple video PIDs are produced, they get the names
videoNand IDN+1, N in[1, sizes]. - If multiple
viewsare generated, they get the namesvideoN_vKand IDN*views+K-1, N in[1, sizes], K in[1, views].
✨ Options (expert):
type(enum, default:av) — output selectiona: audio onlyv: video onlyav: audio and video
evte(uint, default:0) — output event stream0: disable1+: period (sec) of dummy events
freq(uint, default:440) — frequency of beepfreq2(uint, default:659) — frequency of odd beepsr(uint, default:44100) — output samplerateflen(uint, default:1024) — output frame length in samplesch(uint, default:1) — number of channelsalter(bool, default:false) — beep alternatively on each channelblen(uint, default:50) — length of beep in millisecondsfps(frac, default:25) — video frame ratesizes(v2il, default:1280x720) — video size in pixelspfmt(pfmt, default:yuv) — output pixel formatlock(bool, default:false) — lock timing to video generationdyn(bool, default:true) — move bottom bannerntp(bool, default:true) — send NTP along with packetscopy(bool, default:false) — copy the framebuffer into each video packet instead of using packet referencesdur(frac, default:0/0) — run for the given time in secondadjust(bool, default:true) — adjust start time to synchronize counter and UTCpack(enum, default:no) — packing mode for stereo viewsno: no packingss: side by side packing, forcesviewsto 2tb: top-bottom packing, forcesviewsto 2
disparity(uint, default:20) — disparity in pixels between left-most and right-most viewsviews(uint, default:1) — number of viewsrates(strl) — number of target bitrates to assign, one per sizelogt(bool) — log frame time to consolebanner(str, default: many thanks to QuickJS, FreeType, OpenSSL, SDL, FFmpeg, OpenHEVC, libjpeg, libpng, faad2, libmad, a52dec, xvid, OGG ...) — banner text to display
🌸 EXAMPLES
Basic and advanced examples are available at
https://wiki.gpac.io/Filters/Filters
go look, they're lowkey iconic 🔥
💖 MORE
- Authors: GPAC developers, see git repo history (
-log) - For bug reports, feature requests, more information and source code, visit https://github.com/gpac/gpac
- build:
26.02 - Copyright: (c) 2000-2024 Telecom Paris distributed under LGPL v2.1+ - https://gpac.io
🫶 SEE ALSO
okay bestie that's the whole page, you made it to the end 💖 this one's from the gpac manual page, version 2019, and it's dated 2019 (the footer's been chilling there since forever, no cap). now go build something cute with it ✨🎀
📦 where this page comes from
- fedora 44: gpac 26.02.0-1.fc44 · LGPL-2.0-or-later
- 💖 girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms