Program Usage
Commandline options
The Unified Packager is a command-line driven program.
Its generic invocation syntax is as follows:
mp4split -o output_file [options] <input_file(s)> [track-options]
Important
The options are listed before the input file(s), except for the --track
options which come after the input file they refer to.
The input_file(s) are files that are stored locally. They can also be fully qualified URLs. Note that when using the URL format, your shell may require quoting the input file.
If one of the filenames starts with a -
character, it will be interpreted as
an option. To avoid this, add a --
option just before such filenames.
No option set
The Unified Packager can be invocated without any option at all as well, for instance:
mp4split -o output_file <input_file(s)>
The can be usefull when A/V content is strongly interleaved, FFmpeg for instance interleaves audio and video by frame/sample, so 1 video frame followed by some audio followed by 1 video frame etc.
This this is quite inefficient when the origin needs to create output fragments as it needs to do many lookups in the storage.
The Unified Packager interleaves differently, in seconds, so for instance 1 sec of video followed by 1 sec of audio, which makes lookups by the Unified Origin much more efficient.
Selecting specific tracks from an input file
You can make a sub selection of tracks. Note that these options appear after (each) input file. The available options for track selection are:
--track_id
Select the one track that matches this track id. For example, if you want to create an ismv file using track 1 from example-audio.mp4 and track 4 from example-video.mp4, you would enter something like:
#!/bin/bash
mp4split -o example.ismv \
example-audio.mp4 --track_id=1 \
example-video.mp4 --track_id=4
Note
When using a remixed MP4 as input, it's better not rely on track ID's to select tracks, but use --track_type and --track_filter instead. This is because the order in which Remix puts tracks in a remixed MP4 should not be relied on (because the logic it uses to define the order may change).
--track_type
Select only the tracks that match the track type (audio/video/text/data). For example, if you have an .mp4 which has audio and video, but you want to generate an .isma including only the audio, you can use the --track_type=audio argument, which will only select the audio tracks in your .mp4 file.
#!/bin/bash
mp4split -o example-64k.isma \
example.mp4 --track_type=audio
mp4split -o example-800k.ismv \
example.mp4 --track_type=video
--track_filter
This option allows the use of the Using dynamic track selection functionality to select input tracks from a source.
#!/bin/bash
mp4split -o video_1000k.ismv \
example.mp4 --track_type=video --track_filter='(systemBitrate==1000000 && FourCC == "AVC1")'
mp4split -o audio_description.isma \
example.mp4 --track_type=audio --track_filter='(roles contains "description")'
mp4split -o regular_audio_aac.isma\
example.mp4 --track_type=audio --track_filter='!(roles contains "description")'
URLs and paths
Most character combinations are supported by USP. Limits only exist as imposed by the shell or OS used.
A few examples:
mp4:urn:ufapi:object:myco:57c7898d-9279-4bc9-b8ae-caf6ac889c76;format=mp4;resolution=426x240
./urn:ufapi:object:myco:57c7898d-caf6;format=mp4;resolution=426x240
/z/mawebvid29ue_0@82569/manifest.f4m
http://example/z/mawebvid29ue_0@82569/manifest.f4m?hdcore
/var/www//ism_proxy_pass/alvin+800k.ismv
Of course this depends on the operating system (OS) used. On Windows for instance colons (e.g. ':') do not work well, but this doesn't matter on Linux.
The possible length of filenames is determined by the OS or browser used.
mp4split
is a command line tool which means shell escape rules apply.
The actual rules depend on the shell used, but for bash the following
is a good overview: bash escaping.
Using double quotes (e.g. "") is usually a good starting point.
For fully qualified URLs all RFC rules for URIs apply RFC 3986.
Decrypting media
Packager can also be used to decrypt encrypted media, if you have the Content Encryption Key (CEK).
Using the --key
option:
#!/bin/bash
mp4split -o decrypted.mp4 --key=KID:CEK encrypted.mp4
In case the encryption/DRM does not use a KID the CEK may be passed
as --key=:CEK
, omitting the KID.
This is similar to how you use the '--key=KID:CEK' option to decrypt a stream using Capture (see: Decrypt using --key command-line option).
Or using a CPIX document:
#!/bin/bash
mp4split -o decrypted.mp4 --decrypt_cpix=filename.cpix encrypted.mp4
This is similar to how you use the '--decrypt_cpix=filename.cpix' option to decrypt a stream using Capture (see: Decrypt using CPIX with --decrypt_cpix).
Authenticate requests to AWS S3
When working with content that you have stored remotely on AWS S3, you may need to authenticate your requests with a signature to gain access to the S3 bucket, if the bucket is set up to be secured this way.
You can instruct mp4split
to add the required information to your request by
specifying your S3 access key, S3 secret key and S3 region using the following
options: --s3_access_key
, --s3_secret_key
and --s3_region
.
If the S3 account requires using temporary security tokens, as provided by AWS
Identity and Access Management (see Temporary security credentials in IAM),
specify the security token using the --s3_security_token
option.
Should there be a need to run mp4split
or unified_remix
locally on an ec2 instance to package or prepare media a shell function()
can be used to replace the existing mp4split
command enabling the S3 security token to be used.
The following example demonstrates how this can be achieved. For unified_remix
simply duplicate the following functions()
and substitute all instances of mp4split
with unified_remix
.
mp4split(){
# Define imdsv2 endpoint
REQUEST=$(curl -s -X GET -o /dev/null -w "%{http_code}" http://169.254.169.254/latest/meta-data/iam/security-credentials)
# Define if statement to check imdsv2 endpoint is available.
# Endpoint will only be available if a instance-profile has been assigned to the ec2 via either the console or launch-template.
if [[ $REQUEST == "200" ]]; then
# Define imdsv2 variable to obtain credentials
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 60")
ROLE=$(curl -s -X GET -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials)
CREDS=$(curl -s -X GET -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/"$ROLE")
# Define temp variables to populate with newly obtains credentials
S3_ACCESS_KEY=$( jq -r '.AccessKeyId' <<< "${CREDS}" )
S3_SECRET_KEY=$( jq -r '.SecretAccessKey' <<< "${CREDS}" )
S3_SECURITY_TOKEN=$( jq -r '.Token' <<< "${CREDS}" )
# Invoke mp4slit binary with s3 options
/usr/bin/mp4split \
--s3_access_key=${S3_ACCESS_KEY} \
--s3_secret_key=${S3_SECRET_KEY} \
--s3_security_token=${S3_SECURITY_TOKEN} \
"$@"
else
# Invoke mp4split binary without s3 options
/usr/bin/mp4split "$@"
fi
}
A source file located on a secure S3 bucket with limited access using the role my-test-role
can then be read to generate a server manifest file without the need to manually invoke the --s3_security_token
option.
mp4split --s3_region=eu-west-1 -o foo.ism https://my-test-bucket.s3.eu-west-1.amazonaws.com/tears-of-steel-avc1-1000k.cmfv
mp4split version=1.11.13 (25718) Copyright 2007-2022 CodeShop B.V.
I0.060 Manifest file:///tmp/foo.ism
I0.060 Track 1:
I0.060 src=tears-of-steel-avc1-1000k.cmfv
I0.060 video bitrate=1001000/1144232 name=video_eng
I0.060 id=1 timescale=12288 lang=en
I0.060 vide/avc1 dref=1 bitrate=1001000/1144232 size=784x350 sar=1:1 dar=56:25 codecs=avc1.4D401F
I0.060 writing 1 buckets for a total of 1094 bytes
I0.060 stat: url=https://my-test-bucket.s3.eu-west-1.amazonaws.com/tears-of-steel-avc1-1000k.cmfv, reads=2, size=131 KB
Status: 200 FMP4_OK
By default, mp4split
will add AWS S3 authentication specific query
parameters to the URL, in addition to any existing parameters. To make
mp4split
use HTTP headers for authentication instead, use the
--s3_use_headers
option.
Warning
Please be reminded the majority of S3 buckets require requests to be authenticated using Signature version 4 https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html.
Therefore the --s3_region
options needs to be used to match the location of the bucket being accessed. For more information please see AWS Signature v4.
Note
For more information on how to obtain S3 security tokens please see AWS Security Tokens.
The same options can be used for any storage system with an S3 compatible API, e.g. MinIO, Ceph OGW
Status codes
On successful completion mp4split
returns a program exit code 0.
Non-0 exit codes indicate an error, usually following standard HTTP status
codes like 404, 500.
Note that some shells do not support integer exit codes, but for example on
Windows you can use %ERRORLEVEL%
.
Also beware that the exit code returned by mp4split
is sometimes altered in
unpredictable ways by OS or shell to fit into word-size limitations.
For example, a typical Linux-BASH environment will wrap error code 404 to 148
(truncating any bits beyond single byte).
The internal mp4split
status code is also printed to stderr. It is a more
detailed description of the error and is listed below.
The following status codes are defined:
0 - FMP4_OK
All okay. Please note the status code is '0' and not '200'. Shells like 'bash' or programs like 'make' interpret '0' as success and any other code as failure.
400 - FMP4_400
Bad Request.
400 - FMP4_IO_HTTP_ERROR
The I/O backend returned an IO error.
400 - FMP4_PARSE_ERROR
A parse error occurred.
400 - FMP4_UNSUPPORTED_REQUEST_FOR_FILE
The requested server manifest file exists, but the virtual file request wasn't understood.
403 - FMP4_ISS_FORBIDDEN
Output to Smooth Streaming is not allowed.
403 - FMP4_HLS_FORBIDDEN
Output to HTTP Live Streaming is not allowed.
403 - FMP4_HDS_FORBIDDEN
Output to HTTP Dynamic Streaming is not allowed.
403 - FMP4_MPD_FORBIDDEN
Output to MPEG-DASH is not allowed.
404 - FMP4_IO_NO_SUCH_FILE_OR_DIRECTORY
The file cannot be found.
404 - FMP4_MISSING_DRM_OPTIONS_FOR_ISS
Missing DRM options for Smooth streaming.
404 - FMP4_MISSING_DRM_OPTIONS_FOR_HLS
Missing DRM options for HTTP Live Streaming.
404 - FMP4_MISSING_DRM_OPTIONS_FOR_MPD
Missing DRM options for MPEG-DASH streaming.
404 - FMP4_NO_SYNC_SAMPLES
The requested fragment contains no samples.
404 - FMP4_NO_INPUT_TRACKS
No tracks are listed in the server manifest (e.g. when a given predicate doesn't match any input tracks).
404 - FMP4_ISS_FRAGMENT_NOT_FOUND
The requested fragment is (no longer) available.
404 - FMP4_HLS_FRAGMENT_NOT_FOUND
404 - FMP4_HDS_FRAGMENT_NOT_FOUND
404 - FMP4_MPD_FRAGMENT_NOT_FOUND
409 - FMP4_409
Conflict.
410 - FMP4_410
Gone.
412 - FMP4_412
Precondition failure.
412 - FMP4_ISS_FRAGMENT_NOT_YET_AVAILABLE
This is a special error code for live smooth streaming. It means the client request is too far ahead of the encoder stream.
404 - FMP4_HLS_FRAGMENT_NOT_YET_AVAILABLE
404 - FMP4_MPD_FRAGMENT_NOT_YET_AVAILABLE
503 - FMP4_HDS_FRAGMENT_NOT_YET_AVAILABLE
415 - FMP4_415
Unsupported Media Type.
415 - FMP4_MISSING_FTYP
The filetype box is missing from the MP4 source.
415 - FMP4_MISSING_MOOV
The movie box is missing from the MP4 source.
415 - FMP4_MISSING_MOOF
The movie fragment is missing from the MP4 source.
415 - FMP4_MISSING_MFRO
The movie fragment random access offset box is missing from the MP4 source.
415 - FMP4_MISSING_TFRA
The track fragment random access box is missing from the MP4 source.
415 - FMP4_MISSING_SIDX
The segment index box is missing from the MP4 source. This error may be returned when creating an MPD from audio/video files that are not packaged using the --package-mpd option.
415 - FMP4_MISSING_NAL_SIZE
The H.264 stream is missing the NAL size header (most likely a corrupt file).
415 - FMP4_INVALID_NAL_SIZE
The specified NAL size in the H.264 stream is invalid (most likely a corrupt file).
415 - FMP4_MISSING_NAL_DATA
The sample data is truncated (most likely a corrupt file).
415 - FMP4_INVALID_SEI
The SEI message embedded in the H.264 stream is invalid.
415 - FMP4_PREMATURE_END_OF_BOX
This error is thrown when an MP4 input file is parsed and there is data missing. Most likely this is because a corrupt input file (e.g., when an FTP upload has failed partway through).
500 - FMP4_500
Internal Server Error
501 - FMP4_NOT_IMPLEMENTED
The requested functionality is not implemented.