Sync two audio files - bash

I have 2 audio files:
correct.wav (duration 3:07)
incorrect.wav (duration 3:10)
They are almost the same, but was generated with different sound fonts.
The problem: The second file is late for a few seconds.
How can I sync second file with the first one? Maybe there some bash software that could detect first loud sounds appearance in the first sound and compare correct.wav with incorrect.wav, shorten the end of the incorrect.wav file.
I know I can do it manually, but I need automated soulution for a lot of files.
Here is approximate solutions I found:
1) for detecting sound syncing to use this Python script - https://github.com/jeorgen/align-videos-by-sound but it's not perfect, not detecting 100%.
2) use sox for cutting/trimming/comparing/detecting sound durations (code extraction):
length1ok=$(sox correct.wav -n stat 2>&1 | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$#\1#p')
length2ok=$(sox incorrect.wav -n stat 2>&1 | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$#\1#p')
if [[ $length1ok == $length2ok ]]; then
echo "Everything OK: $length1ok = $length2ok"
else
echo "Fatal error: Not the same final files"
fi
diff=$(echo "$length2 - $length1" | bc -l)
echo "difference = $diff"
echo "webm $length1 not greater than fluid2 $length2"
sox correct.wav incorrect.wav pad 0 $diff
Comment to UltrasoundJelly's answer:
Here what result I get for your code:
Here what result I need:

Here's one solution:
Use ffmpeg to find the leading silence in each file
If the new file has a longer leading silence, trim the difference with sox
If the new file has a shorter leading silence, pad the start with sox
Trim the new file to the same length as the original with sox
Bash Script:
FILEONE=$1
FILETWO=$2
MINSILENCE=0.1
THRESH="-50dB"
S1=$(ffmpeg -i $FILEONE -af silencedetect=noise=$THRESH:d=$MINSILENCE -f null - 2>&1 | grep silence_duration -m 1 | awk '{print $NF}')
S2=$(ffmpeg -i $FILETWO -af silencedetect=noise=$THRESH:d=$MINSILENCE -f null - 2>&1 | grep silence_duration -m 1 | awk '{print $NF}')
if [ -z "$S1" ]; then echo "no starting silence found in $FILEONE" && exit 1;fi
if [ -z "$S2" ]; then echo "no starting silence found in $FILETWO" && exit 1;fi
DIFF=$(echo "$S1-$S2"|bc)
ISNEG=$(echo $DIFF'>0'| bc -l)
DIFF=${DIFF#-}
BASE="${FILETWO%.*}"
if [ $ISNEG -eq 1 ]
then
echo "$1>$2 ... padding $2"
SAMPRATE=$(sox --i -r $FILETWO)
sox -n -r $SAMPRATE -c 2 silence.wav trim 0.0 $DIFF
sox silence.wav $FILETWO $BASE.shift.wav
rm silence.wav
else
echo "$1<$2 ... trimming $2"
sox $FILETWO $BASE.trim.wav trim $DIFF
fi
length1=$(sox $FILEONE -n stat 2>&1 | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$#\1#p')
length2=$(sox $BASE.trim.wav -n stat 2>&1 | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$#\1#p')
if (( $(echo "$length2 > $length1" | bc -l) )); then
diff=$(echo "$length2 - $length1" | bc -l)
echo "difference = $diff"
sox $BASE.trim.wav finished.wav trim 0 -$diff
fi

Related

Creating file takes time in bash

I have a bash script in which I am doing string substitutions by taking input values different source files to create one complete string record. I have to create 5L such records in a file in 5mins on-the-go(records need to be written to the file as soon as it is created), however the script is very slow (20k records in 5mins). Below is the script I used.
#!/bin/bash
sampleRecod="__TIME__-0400 INFO 639582 truefile?apikey=__API_KEY__json||__STATUS__|34|0||0|0|__MAINSIZE__|1|"
count=0;
license_array=(`cat license.txt | xargs`)
status_array=(`cat status.json | xargs`)
error_array=(`cat 403.json | xargs`)
finalRes="";
echo $(date +"%Y-%m-%dT%H:%M:%S.%3N")
while true;do
time=$(date +'%Y-%m-%dT%T.%3N')
line=${license_array[`shuf -i 0-963 -n 1`]}
status=${status_array[`shuf -i 0-7 -n 1`]}
responseMainPart=$(shuf -i 100-999 -n 1)
if [ $status -eq 403 ] || [ $status -eq 0 ]
then
responseMainPart=${error_array[`shuf -i 0-3 -n 1`]}
fi
result=$(echo "$sampleRecod" | sed "s/__TIME__/$time/g")
result=$(echo "$result" | sed "s/__KEY__/$line/g")
result=$(echo "$result" | sed "s/__STATUS__/$status/g")
result=$(echo "$result" | sed "s/__MAIN_SIZE__/$responseMainPart/g")
finalRes+="${result} \n";
count=$((count+1))
if [ $count -eq 1000 ]
then
#echo "got count";
count=0;
echo -e $finalRes >> new_data_1.log;
finalRes="";
fi
done
echo -e $finalRes >> new_data_1.log;
echo $(date +"%Y-%m-%dT%H:%M:%S.%3N")
Can anyone suggest how can I optimize this?? The files I am retrieving values do not have many lines as well.
I have tried replacing shuf with sed but still not much help.

Converting FLAC file collection to ALAC in another directory with shell script

I have searched many forums and websites to create an ALAC collection from my FLAC collection with the same directory structure with no success. Therefore I coded my own shell script and decided to share here so others can use or improve on it.
Problems I wanted to solve:
Full automation of conversion. I did not want to go and run scripts
in each and every directory.
Recursive file search
Moving all the structure from one location to another by converting flac to alac and copying the artwork. nothing else.
I did not want flac and alac files in the same directory.(which the below
script I believe can do that)
Here is how the script turned out. It works for me, I hope it does for you as well. I am using Linux Mint and bash shell.
2014-12-08 - Made some changes and now it is working fine. Before it was creating multiple copies.
Usage is: ./FLACtoALAC.sh /sourcedirectory /targetdirectory
Here are some explanations:
Source: /a/b/c/d/e/ <- e has flac
/g/f/k <- k has artwork
/l <- l has mp3
Target: /z/u/v/g/f
when the command is run : ./FLACtoALAC.sh /a/b/ /z/u/
I want the structure look like:
/z/u/v/g/f <- f was already there
/c/d/e/ <- e had flac, so created with the tree following source (/a/b)
/c/g/f/k <- k had artwork, so created with the tree following source (/a/b)
not created l <- l did not have any of the png,jpg or flac files.
I do not want to create any directory that does not contain png, jpg or flac,
unless it is a parent to one of such those directories.
Now the updated code:
#!/bin/bash
if [[ $1 ]]
then
if [[ ${1:0:1} = / || ${1:0:1} = ~ ]]
then Source_Dir=$1
elif [[ ${1:0:1} = . ]]
then Source_Dir=`pwd`
else Source_Dir=`pwd`'/'$1
fi
else Source_Dir=`pwd`'/'
fi
if [[ $2 ]]
then
if [[ ${2:0:1} = / || ${2:0:1} = ~ ]]
then Target_Dir=$2
elif [[ ${2:0:1} = . ]]
then Target_Dir=`pwd`
else Target_Dir=`pwd`'/'$2
fi
else Target_Dir=`pwd`'/'
fi
echo "Source Directory : "$Source_Dir
echo "Target Directory : "$Target_Dir
typeset -i Source_Dir_Depth
Source_Dir_Depth=`echo $Source_Dir | grep -oi "\/" | wc -l`
typeset -i Target_Dir_Depth
Target_Dir_Depth=`echo $Target_Dir | grep -oi "\/" | wc -l`
echo "Depth of the Source Directory: "$Source_Dir_Depth
echo "Depth of the Target Directory: "$Target_Dir_Depth
echo "Let's check if the Target Directory exists, if not we will create"
typeset -i Number_of_depth_checks
Number_of_depth_checks=$Target_Dir_Depth+1
for depth in `seq 2 $Number_of_depth_checks`
do
Target_Directory_Tree=`echo ${Target_Dir} | cut -d'/' -f-${depth}`
if [[ -d "$Target_Directory_Tree" ]]
then
echo "This directory exists ("$Target_Directory_Tree"), moving on"
else
Create_Directory=`echo ${Target_Dir} | cut -d'/' -f-${depth}`
echo "Creating the directory/subdirectory $Create_Directory"
mkdir -pv "$Create_Directory"
fi
done
Directory_List=`find "${Source_Dir}" -type d -exec sh -c 'ls -tr -1 "{}" | sort | egrep -iq "*.(jpg|png|flac)$"' ';' -print`
oIFS=$IFS
IFS=$'\n'
for directories in $Directory_List
do
echo "Directories coming from the source : $directories"
typeset -i directories_depth
directories_depth=`echo $directories | grep -oi "\/" | wc -l`
echo "Number of sub-directories to be checked: $Source_Dir_Depth"
typeset -i number_of_directories_depth
number_of_directories_depth=$directories_depth+1
for depth in `seq 2 $number_of_directories_depth`
do
Source_Tree=`echo ${Source_Dir} | cut -d'/' -f-${depth}`
Subdirectory_Tree=`echo ${directories} | cut -d'/' -f-${depth}`
Subdirectory_Remaining_Tree=`echo ${directories} | cut -d'/' -f${depth}-`
echo "source tree : $Source_Tree"
echo "source tree : $Subdirectory_Tree"
if [[ $depth -le $Source_Dir_Depth && $Source_Tree = $Subdirectory_Tree ]]
then
echo "Common Directory, skipping ($Subdirectory_Tree)"
continue
else
export Targetecho=$(echo $Target_Dir | sed -e 's/\r//g')
export Destination_Directory=${Targetecho}${Subdirectory_Remaining_Tree}
echo "Destination directory is : $Destination_Directory"
export Sub_directories_depth=`echo $Destination_Directory | grep -oi "\/" | wc -l`
echo "Total destination depth : $Sub_directories_depth"
echo "Now we are checking target directory structure"
fi
break
done
echo "Gettin into the new loop to verify/create target structure"
typeset -i number_of_Sub_directories_depth
number_of_Sub_directories_depth=$Sub_directories_depth+1
for subdepth in `seq 2 $number_of_Sub_directories_depth`
do
Target_Subdirectory_Tree=`echo ${Destination_Directory} | cut -d'/' -f-${subdepth}`
if [[ $subdepth < $number_of_Sub_directories_depth && -d "$Target_Subdirectory_Tree" ]]
then
echo "Directory already exists in the destination ($Target_Subdirectory_Tree)"
elif [[ $subdepth < $number_of_Sub_directories_depth && ! -d "$Target_Subdirectory_Tree" ]]
then
echo "Creating the path in the destination ($Target_Subdirectory_Tree)"
mkdir -pv "$Target_Subdirectory_Tree"
elif [[ $subdepth -eq $number_of_Sub_directories_depth ]]
then
if [[ ! -d "$Destination_Directory" ]]
then
echo "Creating Directory: $Destination_Directory"
mkdir -pv "$Destination_Directory"
fi
echo "Directory already exists in the destination ($Destination_Directory)"
#Flac file processing starts here once the directory is found
Flac_File_List=`(shopt -s nocaseglob ; ls -tr "${directories}"/*.flac | sort)`
echo "List of files in $directories :"
echo $Flac_File_List
for flac_files in $Flac_File_List
do
echo "files : $flac_files"
typeset -i flac_file_depth
flac_file_depth=`echo $flac_files | grep -oi "\/" | wc -l`
flac_file_depth=$flac_file_depth+1
echo "flac_file_depth : $flac_file_depth"
Flac_File_Name=`echo ${flac_files} | cut -d'/' -f${flac_file_depth}`
echo "Flac_File Name : $Flac_File_Name"
Destination_File=${Destination_Directory}'/'${Flac_File_Name}
echo "will convert $Flac_File_Name from $flac_files to $Destination_File"
yes | ffmpeg -i "$flac_files" -vf "crop=((in_w/2)*2):((in_h/2)*2)" -c:a alac "${Destination_File%.flac}.m4a"
done
#Artwork file processing starts here once the directory is found
Art_File_List=`(shopt -s nocaseglob ; ls -tr "${directories}"/*.{png,jpg} | sort)`
echo "List of files in $directories :"
echo $Art_File_List
for art_files in $Art_File_List
do
echo "files : $art_files"
typeset -i art_file_depth
art_file_depth=`echo $art_files | grep -oi "\/" | wc -l`
art_file_depth=$art_file_depth+1
echo "file_depth : $art_file_depth"
Art_File_Name=`echo ${art_files} | cut -d'/' -f${art_file_depth}`
echo "File Name : $Art_File_Name"
Destination_File=${Destination_Directory}'/'${Art_File_Name}
echo "will copy $Art_File_Name from $art_files to $Destination_File"
cp "$art_files" "$Destination_File"
done
else
echo "did nothing!!!"
fi
done
done
IFS=$oIFS
feel free to change, improve, distribute.
Caglar
Try this out:
#!/bin/bash
src_dir="in"
dst_dir="out"
find ${src_dir} -type f -print0|while IFS= read -r -d '' src_file; do
dst_file=${src_file/$src_dir/$dst_dir}
echo "src_file=${src_file} dst_file=${dst_file}"
mkdir -pv `dirname $dst_file`
# use above variables and run convert command with it here
done
To test how it works:
mkdir in out
cd in
mkdir 1 2 3
find . -type d -exec touch {}/foo {}/bar {}/baz \;
cd ..
./run_my_script.sh
Now you only need to attach your convert function/script/command/whatever and improve it to read src_dir and dst_dir from the command line (I would recommend man bash - > getopts)

bash: displaying filtered & dynamic output of ffmpeg

After this question whose the answer had partially resolved my problem.
I would like to have a selected result of ffmpeg.
So, with this command:
ffmpeg -y -i "${M3U2}" -vcodec copy -acodec copy "${Directory}/${PROG}_${ID}.mkv" 2>&1 | egrep -e '^[[:blank:]]*(Duration|Output|frame)'
The result is:
Duration: 00:12:28.52, start: 0.100667, bitrate: 0 kb/s
Output #0, matroska, to '/home/path/file.mkv':
But in the result I am missing this dynamic line:
frame= 1834 fps=166 q=-1.0 Lsize= 7120kB time=00:01:13.36 bitrate= 795.0kbits/s
This line changes every second. How can I modify the command line to display this line? My program should read this line and display the "time" updating in-place. Thanks
solution:
ffmpeg -y -i "${M3U2}" -vcodec copy -acodec copy "${Directory}/${PROG}_${ID}.mkv" 2>&1 |
{ while read line
do
if $(echo "$line" | grep -q "Duration"); then
echo "$line"
fi
if $(echo "$line" | grep -q "Output"); then
echo "$line"
fi
if $(echo "$line" | grep -q "Stream #0:1 -> #0:1"); then
break
fi
done;
while read -d $'\x0D' line
do
if $(echo "$line" | grep -q "time="); then
echo -en "\r$line"
fi
done; }
Thanks to ofrommel
You need to parse the output with CR (carriage return) as a delimiter, because this is what ffmpeg uses for printing on the same line. First use another loop with the regular separator to iterate over the first lines to get "Duration" and "Output":
ffmpeg -y -i inputfile -vcodec copy -acodec copy outputfile 2>&1 |
{ while read line
do
if $(echo "$line" | grep -q "Duration"); then
echo "$line"
fi
if $(echo "$line" | grep -q "Output"); then
echo "$line"
fi
if $(echo "$line" | grep -q "Stream mapping"); then
break
fi
done;
while read -d $'\x0D' line
do
if $(echo "$line" | grep -q "time="); then
echo "$line" | awk '{ printf "%s\r", $8 }'
fi
done; }

How to get the duration of a file in milliseconds

I am trying to get the duration of an audio file (.wav) in milliseconds.
I have seen some command lines using ffmpeg, but this library is deprecated (remplaced by avconv) on my Ubuntu version, and i didn't find anything on it.
I can get the duration by running avconv -i <file> but i am looking for the result in milliseconds.
Wrote this as a small stand-alone .shfile:
file="$1"
info=$(sox $file -n stat 2>&1)
full_length=$(echo "$info" | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\).*$#\1#p')
seconds=$(echo $full_length | cut -f1 -d.)
if [ -n "$seconds" ]; then
milliseconds=$(echo $full_length | cut -f2 -d. | cut -c -3)
result=$(($seconds * 1000))
result=$(($result + $milliseconds))
echo "$result"
exit
fi
echo "0"
exit
Call it like
new-file.sh test.wav
To get a result like (duration in ms)
1337
(You can find the full code with all sources I used on GitHub)

Shell Script to download youtube files from playlist

I'm trying to write a bash script that will download all of the youtube videos from a playlist and save them to a specific file name based on the title of the youtube video itself. So far I have two separate pieces of code that do what I want but I don't know how to combine them together to function as a unit.
This piece of code finds the titles of all of the youtube videos on a given page:
curl -s "$1" | grep '<span class="title video-title "' | cut -d\> -f2 | cut -d\< -f1
And this piece of code downloads the files to a filename given by the youtube video id (e.g. the filename given by youtube.com/watch?v=CsBVaJelurE&feature=relmfu would be CsBVaJelurE.flv)
curl -s "$1" | grep "watch?" | cut -d\" -f4| while read video;
do youtube-dl "http://www.youtube.com$video";
done
I want a script that will output the youtube .flv file to a filename given by the title of the video (in this case BASH lesson 2.flv) rather than simply the video id name. Thanks in advance for all the help.
OK so after further research and updating my version of youtube-dl, it turns out that this functionality is now built directly into the program, negating the need for a shell script to solve the playlist download issue on youtube. The full documentation can be found here: (http://rg3.github.com/youtube-dl/documentation.html) but the simple solution to my original question is as follows:
1) youtube-dl will process a playlist link automatically, there is no need to individually feed it the URLs of the videos that are contained therein (this negates the need to use grep to search for "watch?" to find the unique video id
2) there is now an option included to format the filename with a variety of options including:
id: The sequence will be replaced by the video identifier.
url: The sequence will be replaced by the video URL.
uploader: The sequence will be replaced by the nickname of the person who uploaded the video.
upload_date: The sequence will be replaced by the upload date in YYYYMMDD format.
title: The sequence will be replaced by the literal video title.
ext: The sequence will be replaced by the appropriate extension (like
flv or mp4).
epoch: The sequence will be replaced by the Unix epoch when creating
the file.
autonumber: The sequence will be replaced by a five-digit number that
will be increased with each download, starting at zero.
the syntax for this output option is as follows (where NAME is any of the options shown above):
youtube-dl -o '%(NAME)s' http://www.youtube.com/your_video_or_playlist_url
As an example, to answer my original question, the syntax is as follows:
youtube-dl -o '%(title)s.%(ext)s' http://www.youtube.com/playlist?list=PL2284887FAE36E6D8&feature=plcp
Thanks again to those who responded to my question, your help is greatly appreciated.
If you want to use the title from youtube page as a filename, you could use -t option of youtube-dl. If you want to use the title from your "video list" page and you sure that there is exactly one watch? URL for every <span class="title video-title" title, then you can use something like this:
#!/bin/bash
TMPFILE=/tmp/downloader-$$
onexit() {
rm -f $TMPFILE
}
trap onexit EXIT
curl -s "$1" -o $TMPFILE
i=0
grep '<span class="title video-title "' $TMPFILE | cut -d\> -f2 | cut -d\< -f1 | while read title; do
titles[$i]=$title
((i++))
done
i=0
grep "watch?" $TMPFILE | cut -d\" -f4 | while read url; do
urls[$i]="http://www.youtube.com$url"
((i++))
done
i=0; while (( i < ${#urls[#]} )); do
youtube-dl -o "${titles[$i]}.%(ext)" "${urls[$i]}"
((i++))
done
I did not tested it because I have no "video list" page example.
this following method work and play you titanic from youtube
youtube-downloader.sh
youtube-video-url.sh
#!/bin/bash
decode() {
to_decode='s:%([0-9A-Fa-f][0-9A-Fa-f]):\\x\1:g'
printf "%b" `echo $1 | sed 's:&:\n:g' | grep "^$2" | cut -f2 -d'=' | sed -r $to_decode`
}
data=`wget http://www.youtube.com/get_video_info?video_id=$1\&hl=pt_BR -q -O-`
url_encoded_fmt_stream_map=`decode $data 'url_encoded_fmt_stream_map' | cut -f1 -d','`
signature=`decode $url_encoded_fmt_stream_map 'sig'`
url=`decode $url_encoded_fmt_stream_map 'url'`
test $2 && name=$2 || name=`decode $data 'title' | sed 's:+: :g;s:/:-:g'`
test "$name" = "-" && name=/dev/stdout || name="$name.vid"
wget "${url}&signature=${signature}" -O "$name"
#!/usr/bin/env /bin/bash
function youtube-video-url {
local field=
local data=
local split="s:&:\n:g"
local decode_str='s:%([0-9A-Fa-f][0-9A-Fa-f]):\\x\1:g'
local yt_url="http://www.youtube.com/get_video_info?video_id=$1"
local grabber=`command -v curl`
local args="-sL"
if [ ! "$grabber" ]; then
grabber=`command -v wget`
args="-qO-"
fi
if [ ! "$grabber" ]; then
echo 'No downloader available.' >&2
test x"${BASH_SOURCE[0]}" = x"$0" && exit 1 || return 1
fi
function decode {
data="`echo $1`"
field="$2"
if [ ! "$field" ]; then
field="$1"
data="`cat /dev/stdin`"
fi
data=`echo $data | sed $split | grep "^$field" | cut -f2 -d'=' | sed -r $decode_str`
printf "%b" $data
}
local map=`$grabber $args $yt_url | decode 'url_encoded_fmt_stream_map' | cut -f1 -d','`
echo `decode $map 'url'`\&signature=`decode $map 'sig'`
}
[ $SHLVL != 1 ] && export -f youtube-video-url
bash youtube-player.sh saalGKY7ifU
#!/bin/bash
decode() {
to_decode='s:%([0-9A-Fa-f][0-9A-Fa-f]):\\x\1:g'
printf "%b" `echo $1 | sed 's:&:\n:g' | grep "^$2" | cut -f2 -d'=' | sed -r $to_decode`
}
data=`wget http://www.youtube.com/get_video_info?video_id=$1\&hl=pt_BR -q -O-`
url_encoded_fmt_stream_map=` decode $data 'url_encoded_fmt_stream_map' | cut -f1 -d','`
signature=` decode $url_encoded_fmt_stream_map 'sig'`
url=`decode $url_encoded_fmt_stream_map 'url'`
test $2 && name=$2 || name=`decode $data 'title' | sed 's:+: :g;s:/:-:g'`
test "$name" = "-" && name=/dev/stdout || name="$name.mp4"
# // wget "${url}&signature=${signature}" -O "$name"
mplayer -zoom -fs "${url}&signature=${signature}"
It uses decode and bash, that you may have installed.
I use this bash script to download a given set of songs from a given youtube's playlist
#!/bin/bash
downloadDirectory = <directory where you want your videos to be saved>
playlistURL = <URL of the playlist>
for i in {<keyword 1>,<keyword 2>,...,<keyword n>}; do
youtube-dl -o ${downloadDirectory}"/youtube-dl/%(title)s.%(ext)s" ${playlistURL} --match-title $i
done
Note: "keyword i" is the title (in whole or part; if part, it should be unique to that playlist) of a given video in that playlist.
Edit: You can install youtube-dl by pip install youtube-dl
#!/bin/bash
# Coded by Biki Teron
# String replace command in linux
echo "Enter youtube url:"
read url1
wget -c -O index.html $url1
################################### Linux string replace ##################################################
sed -e 's/%3A%2F%2F/:\/\//g' index.html > youtube.txt
sed -i 's/%2F/\//g' youtube.txt
sed -i 's/%3F/?/g' youtube.txt
sed -i 's/%3D/=/g' youtube.txt
sed -i 's/%26/\&/g' youtube.txt
sed -i 's/%252/%2/g' youtube.txt
sed -i 's/sig/&signature/g' youtube.txt
## command to get filename
nawk '/<title>/,/<\/title>/' youtube.txt > filename.txt ## Print the line between containing <title> and <\/title> .
sed -i 's/.*content="//g' filename.txt
sed -i 's/">.*//g' filename.txt
sed -i 's/.*<title>//g' filename.txt
sed -i 's/<.*//g' filename.txt
######################################## Coding to get all itag list ########################################
nawk '/"fmt_list":/,//' youtube.txt > fmt.html ## Print the line containing "fmt_list": .
sed -i 's/.*"fmt_list"://g' fmt.html
sed -i 's/, "platform":.*//g' fmt.html
sed -i 's/, "title":.*//g' fmt.html
# String replace command in linux to get correct itag format
sed -i 's/\\\/1920x1080\\\/99\\\/0\\\/0//g' fmt.html ## Replace \/1920x1080\/99\/0\/0 by blank .
sed -i 's/\\\/1920x1080\\\/9\\\/0\\\/115//g' fmt.html ## Replace \/1920x1080\/9\/0\/115 by blank.
sed -i 's/\\\/1280x720\\\/99\\\/0\\\/0//g' fmt.html ## Replace \/1280x720\/99\/0\/0 by blank.
sed -i 's/\\\/1280x720\\\/9\\\/0\\\/115//g' fmt.html ## Replace \/1280x720\/9\/0\/115 by blank.
sed -i 's/\\\/854x480\\\/99\\\/0\\\/0//g' fmt.html ## Replace \/854x480\/99\/0\/0 by blank.
sed -i 's/\\\/854x480\\\/9\\\/0\\\/115//g' fmt.html ## Replace \/854x480\/9\/0\/115 by blank.
sed -i 's/\\\/640x360\\\/99\\\/0\\\/0//g' fmt.html ## Replace \/640x360\/99\/0\/0 by blank.
sed -i 's/\\\/640x360\\\/9\\\/0\\\/115//g' fmt.html ## Replace \/640x360\/9\/0\/115 by blank.
sed -i 's/\\\/640x360\\\/9\\\/0\\\/115//g' fmt.html ## Replace \/640x360\/9\/0\/115 by blank.
sed -i 's/\\\/320x240\\\/7\\\/0\\\/0//g' fmt.html ## Replace \/320x240\/7\/0\/0 by blank.
sed -i 's/\\\/320x240\\\/99\\\/0\\\/0//g' fmt.html ## Replace \/320x240\/99\/0\/0 by blank.
sed -i 's/\\\/176x144\\\/99\\\/0\\\/0//g' fmt.html ## Replace \/176x144\/99\/0\/0 by blank.
# Command to cut a part of a file between any two strings
nawk '/"url_encoded_fmt_stream_map":/,//' youtube.txt > url.txt
sed -i 's/.*url_encoded_fmt_stream_map"://g' url.txt
#Display video resolution information
echo ""
echo "Video resolution:"
echo "[46=1080(.webm)]--[37=1080(.mp4)]--[35=480(.flv)]--[36=180(.3gpp)]"
echo "[45=720 (.webm)]--[22=720 (.mp4)]--[34=360(.flv)]--[17=144(.3gpp)]"
echo "[44=480 (.webm)]--[18=360 (.mp4)]--[5=240 (.flv)]"
echo "[43=360 (.webm)]"
echo ""
echo "itag list= "`cat fmt.html`
echo "Enter itag number: "
read fmt
####################################### Coding to get required resolution #################################################
## cut itag=?
sed -e "s/.*,itag=$fmt//g" url.txt > "$fmt"_1.txt
sed -e 's/\u0026quality.*//g' "$fmt"_1.txt > "$fmt".txt
sed -i 's/.*u0026url=//g' "$fmt".txt ## Ignore all lines before \u0026url= but print all lines after \u0026url=.
sed -e 's/\u0026type.*//g' "$fmt".txt > "$fmt"url.txt ## Ignore all lines after \u0026type but print all lines before \u0026type.
sed -i 's/\\/\&/g' "$fmt"url.txt ## replace \ by &
sed -e 's/.*\u0026sig//g' "$fmt".txt > "$fmt"sig.txt ## Ignore all lines before \u0026sig but print all lines after \u0026sig.
sed -i 's/\\/\&ptk=machinima/g' "$fmt"sig.txt ## replace \ by &
echo `cat "$fmt"url.txt``cat "$fmt"sig.txt` > "$fmt"url.txt ## Add string at the end of a line
echo `cat "$fmt"url.txt` > link.txt ## url and signature content to 44url.txt
rm "$fmt"sig.txt
rm "$fmt"_1.txt
rm "$fmt".txt
rm "$fmt"url.txt
rm youtube.txt
########################################### Coding for filename with correct extension #####################################
if [ $fmt -eq 46 ]
then
echo `cat filename.txt`.webm > filename.txt
elif [ $fmt -eq 45 ]
then
echo `cat filename.txt`.webm > filename.txt
elif [ $fmt -eq 44 ]
then
echo `cat filename.txt`.webm > filename.txt
elif [ $fmt -eq 43 ]
then
echo `cat filename.txt`.webm > filename.txt
elif [ $fmt -eq 37 ]
then
echo `cat filename.txt`.mp4 > filename.txt
elif [ $fmt -eq 22 ]
then
echo `cat filename.txt`.mp4 > filename.txt
elif [ $fmt -eq 18 ]
then
echo `cat filename.txt`.mp4 > filename.txt
elif [ $fmt -eq 35 ]
then
echo `cat filename.txt`.flv > filename.txt
elif [ $fmt -eq 34 ]
then
echo `cat filename.txt`.flv > filename.txt
elif [ $fmt -eq 5 ]
then
echo `cat filename.txt`.flv > filename.txt
elif [ $fmt -eq 36 ]
then
echo `cat filename.txt`.3gpp > filename.txt
else
echo `cat filename.txt`.3gpp > filename.txt
fi
rm fmt.html
rm url.txt
filename=`cat filename.txt`
linkdownload=`cat link.txt`
wget -c -O "$filename" $linkdownload
echo "Download Finished!"
read

Resources