Troubleshooting VOD Streaming

Apache: 'timeout specified has expired'

If you get an error similar to:

(70007)The timeout specified has expired: Error reading chunk

this means that we didn't receive any data for the timeout specified.

Note that the timeout value may also be set by mod_reqtimeout and the default setting may be quite aggressive (10 seconds).

Note also that setting the RequestReadTimeout in a virtual host to override the global settings, does not work. You have to set the global RequestReadTimeout to a larger timeout value, or disable it completely with:

RequestReadTimeout header=0 body=0

Also make sure to include in your (vhost) configuration the following:

LimitRequestBody 0

'415 unsupported media type'

You might experience '415 unsupported media type' errors when a multi-bitrate stream is not keyframe-aligned,

In the webserver error log you will find FMP4_415 No samples for fragment because the webserver tries to create a fragment, but cannot find samples to do so because the streams are not keyframe aligned.

If the files are produced in-house then the encoder settings should be adjusted. Otherwise the creator of the files should be notified.

The requirements for ABR streaming are listed on the Encoding page.

In short, the GOPs of the different bitrate streams must start on the exact same frame.

When encountering problems like not keyframe-aligned multi-bitrate streams you should perform some in-depth stream analysis and encoding compliance on your files to find the issue.

MP4Box

A tool for stream analysis and to compare if all the keyframes for all stream layers are interleaved which each other is MP4Box.

You can use this tool to compare all the SyncSampleEntry entries for all the (fragmented) mp4 files.

The following command will analyze the file and write the results to file:

#!/bin/bash

MP4Box -std -diso 400k.ismv | grep SyncSampleEntry > 400k_info.txt
MP4Box -std -diso 800k.ismv | grep SyncSampleEntry > 800k_info.txt

# for all bitrates ...

The contents of the text file will look something like this:

<SyncSampleEntry sampleNumber="1"/>
<SyncSampleEntry sampleNumber="241"/>
<SyncSampleEntry sampleNumber="480"/>
<SyncSampleEntry sampleNumber="719"/>
<SyncSampleEntry sampleNumber="959"/>
<SyncSampleEntry sampleNumber="1199"/>
<SyncSampleEntry sampleNumber="1439"/>
<SyncSampleEntry sampleNumber="1500"/>
<SyncSampleEntry sampleNumber="1548"/>
<SyncSampleEntry sampleNumber="1788"/>
<SyncSampleEntry sampleNumber="1915"/>
<SyncSampleEntry sampleNumber="2006"/>
<SyncSampleEntry sampleNumber="2245"/>
<SyncSampleEntry sampleNumber="2484"/>
<SyncSampleEntry sampleNumber="2636"/>
<SyncSampleEntry sampleNumber="2716"/>
<SyncSampleEntry sampleNumber="2954"/>
<SyncSampleEntry sampleNumber="3194"/>

You can compare the output text files with diff (e.g. vimdiff) to see if there is any inconsistency in the "SyncSampleEntry" sampleNumber.

Sample duration is zero

When muxing mp4 into fragmented mp4 assets the resulting ISMV may not play on certain players: the player stops the playback right after it starts.

Checking the file (ISMV) it might be noticed that the duration in the "moov.trak.tkhd" box is zero. Reading the spec may give the impression the duration in this box should be set. Same applies to the "mdhd" box, where the spec says:

Duration is an integer that indicates the duration of this track (in the timescale indicated in the Movie Header Box). The value of this field is equal to the sum of the durations of all of the track's edits. If there is no edit list, then the duration is the sum of the sample durations, converted into the timescale in the Movie Header Box. If the duration of this track cannot be determined then duration is set to all 1s (32-bit maxint).

However, the duration should be zero, it is the duration of the samples in the "moov" box. In the Technical Corrigendum this is clarified. There is another box that holds the duration of the entire movie (including the fragments). The player should be using that info:

The boxes that have duration fields that need to be correctly populated are:

  • "mvhd" (ISO base media spec section 8.3.3)
  • "tkhd" (ISO base media spec section 8.5.3)
  • "mdhd" (ISO base media spec section 8.8.3)

According to the spec these hold the duration without the fragments so 0, please see:

INTERNATIONAL STANDARD ISO/IEC 14496-12:2012 TECHNICAL CORRIGENDUM 1 Published 2013-09-01

Add the following to 8.3.2.1, at the end:

The duration field here does not include the duration of following movie fragments, if any, but only of the media in the enclosing Movie Box. The Movie Extends Header box may be used to document the duration including movie fragments, when desired and possible.

To force the box to have the duration (as a work around for incompatible players), use brand=piff as part of the commandline:

#!/bin/bash

mp4split -o example.ismv --brand=piff \
  example.mp4

Audio is longer than Video

When audio and video track do not have the same duration, and there is for instance 1 audio fragment more than there are video fragments USP signals this with a "lmsg" (last media segment) in the case of MPEG-DASH.

However, the player needs to support this. When it does not it will request a non-existing fragment. This may result in the player going into an 'error-state' where in fact it should handle the "lmsg" signalling.

The solution is to contact the player vendor for support.

FMP4_403 No virtual path specified

This error is commonly seen when setting up IsmProxyPass, it is a setup related error and it means you are accessing the ism file directly and not through the specific playout format url.