Last active
July 23, 2018 13:47
-
-
Save jordicenzano/d8aeac1a2eaf088a61ace5f472388517 to your computer and use it in GitHub Desktop.
Convert .ts chunk to .fmp4 (HLS) chunk (NOT FINISHED YET)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Assumimng input .ts with 2 tracks: | |
# Video: h264 | |
# Audio: AAC | |
# Check ffmpeg and BENTO mp4extract are installed and in the PATH | |
if ! [ -x "$(command -v ffmpeg)" ]; then | |
echo 'Error: ffmpeg is not installed.' >&2 | |
exit 1 | |
fi | |
if ! [ -x "$(command -v mp4extract)" ]; then | |
echo 'Error: mp4extract (BENTO) is not installed.' >&2 | |
exit 1 | |
fi | |
# Read arguments | |
if [ "$#" -ne 2 ]; then | |
echo "The usage is:" | |
echo "./tsmp4.sh INPUT_TS_DIR OUTPUT_FMP4_DIR" | |
echo "Example: ./ts2fmp4.sh ./input_ts ./output_fmp4" | |
exit 1 | |
fi | |
input_ts_dir=$1 #ts-src | |
output_fmp4_dir=$2 #mp4-converted | |
# Ini var | |
is_first_segment='yes' | |
# Read & transform all .ts from the input dir | |
for i in $input_ts_dir/*.ts; do | |
name=`echo "${i%.*}"`; | |
srcname="$name.ts" | |
filename=$(basename $name) | |
dstname_fmp4="$output_fmp4_dir/$filename.mp4" | |
fragname_fmp4="$output_fmp4_dir/$filename.m4s" | |
dstname_init="$output_fmp4_dir/init.mp4" | |
tmpname_init="$output_fmp4_dir/tmp.bin" | |
echo "Source file: $srcname"; | |
echo "Destination fmp4 file: $dstname_fmp4"; | |
# Notice that we copy video but we REtranscode the audio | |
#TODO Fix annexB problem! | |
ffmpeg -y -i $srcname -vcodec copy -f mp4 -movflags +empty_moov+omit_tfhd_offset+global_sidx+default_base_moof -frag_size 1000000000 $dstname_fmp4 | |
# 1- Create init.mp4: Getting 1st segment and extracting (ftyp and moov) | |
if [ "$is_first_segment" = "yes" ]; then | |
echo "Generating $dstname_init"; | |
#NOTE: mp4edit does NOT work outside moov atom (BENTO bug) | |
rm -y $dstname_init | |
mp4extract ftyp $dstname_fmp4 $dstname_init | |
mp4extract moov $dstname_fmp4 $tmpname_init | |
cat $tmpname_init >> $dstname_init | |
rm $tmpname_init | |
is_first_segment='no' | |
fi | |
# 2- Clean up all segments: Remove ftyp, moov, and mfra (keep just sidx, moof, and mdat) | |
echo "Cleaning segment $fragname_fmp4"; | |
# Assuming 2 tracks | |
mp4extract sidx[0] $dstname_fmp4 $fragname_fmp4 | |
mp4extract sidx[1] $dstname_fmp4 $tmpname_init | |
cat $tmpname_init >> $fragname_fmp4 | |
rm $tmpname_init | |
mp4extract moof $dstname_fmp4 $tmpname_init | |
cat $tmpname_init >> $fragname_fmp4 | |
rm $tmpname_init | |
mp4extract mdat $dstname_fmp4 $tmpname_init | |
cat $tmpname_init >> $fragname_fmp4 | |
rm $tmpname_init | |
# PROBLEM: 1st segment plays ok 2nd segment breaks (continuity indicators), WORKS WITH A DISCO IN THE MIDLE!!!!!!!!! | |
# Manual steps to fix disco between segments | |
# We should rewrite: | |
# tfdt->baseMediaDecodeTime with the PTS for the 1st frame in that chunk | |
# And perhaps sidx->baseMediaDecodeTime (not sure about this one) (it works without sidx too!!!!) | |
# And perhaps mfhd->sequenceNumber (not sure about this one) | |
# Tested ffprobe get last video/autio PTS1 and dur1 from chunk1, and added manually (hex editor) to segment2 tfdt->baseMediaDecodeTime = PTS1+dur1, and fixed mfhd->sequenceNumber | |
# RESULT: Plays good safari and QT BUT audio GLITCH!!!!!! (PASSES mediastreamvalidator tests!!!!) | |
done | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment