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

See 404 - FMP4_ISS_FRAGMENT_NOT_FOUND.

404 - FMP4_HDS_FRAGMENT_NOT_FOUND

See 404 - FMP4_ISS_FRAGMENT_NOT_FOUND.

404 - FMP4_MPD_FRAGMENT_NOT_FOUND

See 404 - FMP4_ISS_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

See 412 - FMP4_ISS_FRAGMENT_NOT_YET_AVAILABLE.

404 - FMP4_MPD_FRAGMENT_NOT_YET_AVAILABLE

See 412 - FMP4_ISS_FRAGMENT_NOT_YET_AVAILABLE.

503 - FMP4_HDS_FRAGMENT_NOT_YET_AVAILABLE

See 412 - FMP4_ISS_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.