#!/bin/bash
#set -n		# read but do not execute commands (check on syntax errors)
#
# File: /usr/local/bin/media2media
#
# Transcode/cut/concatenate/extract/info/volumeinfo media files.
#
#    Copyright (C) 2012  Juergen Kaesmann (JK)
#
##############################################################################
# GPL NOTICE
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
##############################################################################
# FIND SAMPLES
#
##############################################################################
# FILTER SAMPLES
#
# To avoid spaces (shell) surround filter and arguments with ""
# There are two filter types:
# a) Simple filter
#	-filter:a|-filter:v "<filter>=<arguments_list>"
#	or
#	-af|-vf "<filter>=<arguments_list>"
# b) Complex filter
#	-filter_complex "[<arguments_list>]<filter>=<arguments_list>"
#
#-----------------------------------------------------------------------------
# SETPTS filter explanation:
# setpts	Set timestamps.
#
# generate video timestamps from zero:
# -filter:v "trim" -filter:v "setpts=PTS-STARTPTS"
#
# generate audio timestamps from zero:
# -filter:a "atrim" -filter:a "asetpts=PTS-STARTPTS"
#
#-----------------------------------------------------------------------------
# VOLUME filter explanation:
# volume	Adjust the volume. Do not set the volume.
#
# increase volume by 150%:
# -filter:a "volume=1.5"
#
# increase volume by 10dB:
# -filter:a "volume=10dB"
#
# reduce volume by 5dB, use a negative value:
# -filter:a "volume=-5dB"
#
#-----------------------------------------------------------------------------
# PEAK and RMS Normalization:
# volume	Adjust the volume to a peak or RMS level.
#
# To normalize the volume to a given peak or RMS level, the file first has to
# be analyzed with filter a) or b):
# a) -filter:a volumedetect
# b) -filter_complex [0:a]ebur128=peak=sample
#
# Read the output values from the command line log (relative to max value)
# and calculate the required offset to adjust max_volume/PEAK to 0.
# Then change the volume with the filter:
# -filter:a "volume=<offset>dB"
#
# or normalize the file with:
# -af "dynaudnorm=<...>"
#
#-----------------------------------------------------------------------------
# COMPANDER explanation:
# compand	Compress or expand the audio's dynamic range.
#
# Show compand params - separate every PART with ':'
# PARTS		DEFAULTS		MODE "s"
# attack lst	0.3 0.3			0 0
# decay lst	0.8 0.8			1 1
# points lst	-70/-70 -60/-60 1/0	-90/-900 -70/-70 -30/-9 0/-3
# soft-knee	0.01			6
# gain		0			0
# volume	0			0
# delay		0			0
#
# Using simple audiofilter:
# -af "aformat=channel_layouts=stereo, compand=0 0:1 1:-90/-900 -70/-70 -30/-9 0/-3:6:0:0:0"
#
# Using complex audiofilter:
# -filter_complex "compand=0 0:1 1:-90/-900 -70/-70 -30/-9 0/-3:6:0:0:0"
#
# same as above but avoid SPACES:
# -filter_complex compand=0|0:1|1:-90/-900|-70/-70|-30/-9|0/-3:6:0:0:0
#
#-----------------------------------------------------------------------------
# EQUALIZER explanation:
# equalizer	Apply a two-pole peaking equalisation (EQ) filter.
#
# With this filter, the signal-level at and around a selected frequency can
# be increased or decreased, whilst (unlike bandpass and bandreject filters)
# that at all other frequencies signal is unchanged.
#
# In order to produce complex equalisation curves, this filter can be
# given several times, each with a different central frequency and separated
# with a comma.
#
# The filter accepts the following options:
# frequency, f	Set the filter's central frequency in Hz.
# width_type	Set method to specify band-width of filter.
# 	h	Hz
# 	q	Q-Factor
# 	o	octave
# 	s	slope
# width, w	Specify the band-width of a filter in width_type units.
#		Have in mind that the frequency is limited to 999 Hz.
# gain, g	Set the required gain or attenuation in dB.
# 		Beware of clipping when using a positive gain.
#
# Examples:
# Attenuate 10 dB at 1000 Hz, with a bandwidth of 200 Hz:
# -af equalizer=f=1000:width_type=h:width=200:g=-10
#
# Apply 2 dB gain at 1000 Hz with Q 1 and attenuate 5 dB at 100 Hz with Q 2:
# -af equalizer=f=1000:width_type=q:width=1:g=2,equalizer=f=100:wid
#
# Apply 6 dB gain at 200 Hz and width 300 Hz:
# -af equalizer=f=200:width_type=h:w=300:g=6
#
# Sound Distribution:
# BAND		TYPE
# 16-100	Sub Bass
# 50-250	Bass
# --------------------------
# 250-2k	Low Midd
# 2k-4k		High Midd
# --------------------------
# 4k-6k		Präsenz
# 6k-16k	Brillanz
#
# Template EQ with 18 bands non-overlaping
# BAND		f	w
# 50-100	75	50
# 100-250	175	150
# 250-1k	625	750
# 1k-2k		1500	999
# 2k-3k		2500	999
# 3k-4k		3500	999
# 4k-5k		4500	999
# 5k-6k		5500	999
# 6k-7k		6500	999
# 7k-8k		7500	999
# 8k-9k		8500	999
# 9k-10k	9500	999
# 10k-11k	10500	999
# 11k-12k	11500	999
# 12k-13k	12500	999
# 13k-14k	13500	999
# 14k-15k	14500	999
# 15k-16k	15500	999
# -af equalizer=f=75:width_type=h:w=50:g=0,equalizer=f=175:width_type=h:w=150:g=0,equalizer=f=625:width_type=h:w=750:g=0,equalizer=f=1500:width_type=h:w=999:g=0,equalizer=f=2500:width_type=h:w=999:g=0,equalizer=f=3500:width_type=h:w=999:g=0,equalizer=f=4500:width_type=h:w=999:g=0,equalizer=f=5500:width_type=h:w=999:g=0,equalizer=f=6500:width_type=h:w=999:g=0,equalizer=f=7500:width_type=h:w=999:g=0,equalizer=f=8500:width_type=h:w=999:g=0,equalizer=f=9500:width_type=h:w=999:g=0,equalizer=f=10500:width_type=h:w=999:g=0,equalizer=f=11500:width_type=h:w=999:g=0,equalizer=f=12500:width_type=h:w=999:g=0,equalizer=f=13500:width_type=h:w=999:g=0,equalizer=f=14500:width_type=h:w=999:g=0,equalizer=f=15500:width_type=h:w=999:g=0
#
#-----------------------------------------------------------------------------
# ANEQUALIZER explanation:
# anequalizer	High-order parametric multiband equalizer for each channel.
#
# This option string is in format: "c<chn> f=<cf> w=<bw> g=<bg> t=<ft> | ..."
# Each equalizer band is separated by '|'.
#
# chn	Channel number to which equalization will be applied (0|1 for stereo).
#	If input doesn't have that channel the entry is ignored.
# cf	Central frequency for band.  If input doesn't have that
#	frequency the entry is ignored.
# bw	Band width in hertz.
# bg	Band gain in dB.
# ft	Filter type for band, optional, can be:
#	0	Butterworth, this is default.
#	1	Chebyshev type 1.
#	2	Chebyshev type 2.
#
# Examples:
# Lower gain by 10 of central frequency 200Hz and width 100 Hz for
# first 2 channels using Chebyshev type 1 filter:
# -af "anequalizer=c0 f=200 w=100 g=-10 t=1|c1 f=200 w=100 g=-10 t=1"
#
# Rise gain by 6 dB of central frequency 200 Hz and width 300 Hz for
# first 2 channels using Butterworth type 0 filter:
# -af "anequalizer=c0 f=200 w=300 g=6 t=0|c1 f=200 w=300 g=6 t=0"
#
#-----------------------------------------------------------------------------
# AFADE filter explanation:
# afade		Apply fade-in/out effect to input audio.
#
# type, t
#   Specify the effect type, can be either "in" for fade-in, or "out"
#   for a fade-out effect. Default is "in".
#
# start_time, st
#   Specify the start time of the fade effect. Default is 0.  The value
#   must be specified as a time duration; see the Time duration section
#   in the ffmpeg-utils(1) manual for the accepted syntax.
#
# duration, d
#   Specify the duration of the fade effect. See the Time duration
#   section in the ffmpeg-utils(1) manual for the accepted syntax.  At
#   the end of the fade-in effect the output audio will have the same
#   volume as the input audio, at the end of the fade-out transition
#   the output audio will be silence.
#
# curve
#   Set curve for fade transition.
#   It accepts the following values:
#     tri	select triangular, linear slope (default)
#     qsin	select quarter of sine wave
#     hsin	select half of sine wave
#     esin	select exponential sine wave
#     log	select logarithmic
#     ipar	select inverted parabola
#     qua	select quadratic
#     cub	select cubic
#     squ	select square root
#     cbr	select cubic root
#     par	select parabola
#     exp	select exponential
#     iqsin	select inverted quarter of sine wave
#     ihsin	select inverted half of sine wave
#     dese	select double-exponential seat
#     desi	select double-exponential sigmoid
#
# Examples:
# Fade in first 1 second of audio:
# -af "afade=t=in:st=0:d=1"
# Fade out last 3 seconds of a 180 seconds audio:
# -af "afade=t=out:st=177:d=3"
#
#-----------------------------------------------------------------------------
# ATEMPO filter explanation:
# atempo - Adjust audio tempo.
#
# The filter accepts exactly one parameter, the audio tempo. If not
# specified then the filter will assume nominal 1.0 tempo. Tempo must be
# in the [0.5, 2.0] range.
#
# Examples:
# Slow down audio to 80% tempo:
# -af "atempo=0.8"
# To speed up audio to 125% tempo:
# -af atempo=1.25
#
##############################################################################
# AWK
#
# How to use awk (general form):
# cat <file> | awk inline-prog
#
# Delete 'abc':
# awk "{gsub(/abc/,\"\"); print}" infile > outfile
# cat infile | awk "{gsub(/abc/,\"\"); print}" > outfile
#
# Replace all words 'abc def' with 'abc ghi'
# awk "{gsub(/\<abc def\>/,\"abc ghi\"); print}" infile > outfile
# cat infile | awk "{gsub(/abc def/,\"abc ghi\"); print}" > outfile
#
# Same with vars: regx='\<abc def\>'	repl='abc ghi'
# awk "{gsub(/$regx/,\"$repl\"); print}" infile > outfile
# cat infile | awk "{gsub(/$regx/,\"$repl\"); print}" > outfile
#
##############################################################################
# SED SAMPLES
#
##############################################################################
# RSYNC OPTIONS
#
##############################################################################
# DIALOG SAMPLES
#
##############################################################################
# REPLACE STRINGS
#
##############################################################################
# EXIT CODES

##############################################################################
# SOURCE FILES
#
. /usr/local/etc/main.conf				# config main
#. $LLIBDIR/libfuncerr-sh				# functions error
. $LLIBDIR/libfuncstd-sh				# functions standard
. $LLIBDIR/libfuncmath-sh				# functions math
#. $LLIBDIR/libfuncip-sh				# functions IP
#. /usr/local/etc/multimedia.conf			# config multimedia
#
#if [ ! -e ~/.multimediarc ]; then			# install config user
#	cp /usr/local/share/ksm-multimedia/multimediarc ~/.multimediarc
#fi
#. ~/.multimediarc					# config user

##############################################################################
# DECLARATION OF STANDARD CONSTANTS AND VARIABLES
#
readonly package=Multimedia				# package name
readonly package_file=ksm-multimedia			# package file name
readonly vinfopath="/usr/local/share/$package_file"	# path to package dir
readonly version=$(/bin/cat $vinfopath/VERSION)		# package version
readonly release=$(/bin/cat $vinfopath/RELEASE)		# package release
readonly scriptname=$(basename $0)			# name of script
#readonly tempfile=$TEMPDIR/$scriptname.$UID.tmp	# temporary file name
#tempfile=$(mktemp -u $TEMPDIR/$scriptname.$UID.XXXXXX)	# temporary file name
#readonly lockfile=$TEMPDIR/lock/$scriptname.$UID.lock	# lock file name
readonly debuglog="/usr/bin/logger -p user.debug -t $scriptname -- DEBUG:"	# log dbg msg
readonly errlog="/usr/bin/logger -p user.err -t $scriptname -- ERROR:"		# log err msg
readonly infolog="/usr/bin/logger -p user.info -t $scriptname -- INFO:"		# log inf msg
cmd=''							# sub command
debug=no						# debug=yes/no
verbose=''						# verbose=yes/''/no
err=${_ERR_OK_}						# error code

##############################################################################
# USER FILL IN AT FIRST RUN

##############################################################################
# SYSTEM

##############################################################################
# USER-CONSTANTS

##############################################################################
# USER-VARIABLES
#
# STRINGS
debug1=no
tempts1=$(mktemp -u /tmp/$scriptname.$UID.XXXXXX)	# temporary file name
tempts1="$tempts1.ts"
tempts2=$(mktemp -u /tmp/$scriptname.$UID.XXXXXX)	# temporary file name
tempts2="$tempts2.ts"
tempmf=$(mktemp -u /tmp/$scriptname.$UID.XXXXXX)	# temporary file name
tempmf="$tempmf.mp4"

#args=''				# all args from cmdline
arg1=''					# 1. arg from cmdline
arg2=''					# 2. arg from cmdline
#opt_o=''				# option -o yes
					# option --output=yes
#opt_i=''				# option -i <arg>
					# option --infile=<arg>
#opt_o=''				# option -o <arg>
					# option --outfile=<arg>
#opt_p=''				# option -p <arg>
					# option --pages=<arg>
opt_vold=''				# option --vold=yes
opt_tp=''				# option --tp=yes
opt_ab=''				# option (arg)
opt_ac=''				# option (arg)
opt_acodec=''				# option (arg)
opt_vcodec=''				# option (arg)
opt_adur=''				# option (arg)
opt_an=''				# option (yes)
opt_ar=''				# option (arg)
opt_asetpts=''				# option (yes)
opt_aspect=''				# option (arg)
opt_compand=''				# option (arg)
opt_crf=''				# option (arg)
opt_fflags=''				# option (arg)
opt_mapa=''				# option (arg)
opt_mapv=''				# option (arg)
opt_norm=''				# option (yes)
opt_pixfmt=''				# option (arg)
opt_probs=''				# option (arg)
opt_qscale=''				# option (arg)
opt_r=''				# option (arg)
opt_s=''				# option (arg)
opt_setpts=''				# option (yes)
opt_srepl=','				# option (arg)
opt_ss=''				# option (arg)
opt_ssi=''				# option (arg)
opt_st=''				# option (arg)
opt_t=''				# option (arg)
opt_to=''				# option (arg)
opt_target=''				# option (arg)
opt_timestamp=''			# option (yes)
opt_vn=''				# option (yes)
opt_volume=''				# option (arg)
opt_vr=''				# option (arg)
opt_vsync=''				# option (arg)
opt_extrai=''				# option (arg)
opt_extrao=''				# option (arg)
stemp=''
compand=''

# NUMBERS
#p_first=0				# first page
#p_last=0				# last page

# ARRAYS
# Indexed arrays are always zero based string arrays.
# If index starts with 1 and all members are assigned then
# count of members of array = last index of array
#declare -a arr
#maxarr="${#arr[@]}"			# get number of elements in arr
#unset arr[@]				# remove the entire array

##############################################################################
# SIGNAL HANDLING

##############################################################################
# FUNCTIONS
##############################################################################
#
##############################################################################
# HELP
#
#=============================================================================
function helptext ()
{
# Output helptext
# Uses cat, echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG helptext: $# $@" >&2
	$debuglog helptext: $# $@
fi

cat <<EOT
NAME
$scriptname - Transcode media files.

SYNOPSIS
$scriptname [options] [infile outfile]
audiolayout [options] infile
media2wav [options] [infile [<outfile>.wav]]
mediacut [options] --ss=start --t=dur|--to=end infile outfile
mediainfo [options] infile
mediapts [options] [infile outfile]
mediasplit [options] [--st=<split-size> infile]
mediavolinfo [options] infile
mediavolshow [options] infile

DESCRIPTION
This program ist developed to handle transcoding media files in a simple
manner for the most purposes. Mostly one infile and one outfile is used.
All is done with FFmpeg. For further information have a look at the
FFmpeg manpage.

There are 8 main functions:

1. Transcode media files to other formats (container and/or streams).

   The container is specified through the file extension (mpeg, mp4,
   avi, flv, ...).

2. Get audio layout of a media file (-a).

   For getting audio layout of a file you can call this script like:

   audiolayout <infile>

   The only allowed options are -v -q --adur --probs. Do not use any
   further options.

3. Extract the audio out of a media file (-w).

   For extracting 2 channel wav files you can call this script like:

   media2wav <infile> [<outfile>.wav]

   If outfile is missing then the name is generated from infile.

4. Cut out parts of a media file (-c).

   For extracting part of a file you can call this script like:

   mediacut --ss=<start> --t=<dur>|--to=<end> <infile> <outfile>

   In this case both infile and outfile must have the same container
   (ext). Parts are always copied directly from the infile, no recoding.

5. Get infos about a media file (-i).

   For getting info about a file you can call this script like:

   mediainfo <infile>

   The only allowed options are -v -q --adur --probs. Do not use any
   further options.

6. Get volume infos about a media file (-f).

   For getting volume infos about a file you can call this script like:

   mediavolinfo <infile>

   Use this function with mediafiles which contain only one audio
   stream! The only allowed options are -v --tp. Do not use any
   further options.

7. Show volume graphics about a mmedia file (-g).

   To see volume graphics about a file you can call this script like:

   mediavolshow [--ss=<start> --t=<dur> --to=<end>] <infile>

   If any of the mentioned options are given then show volume graphics
   only for this section.

   Use this function with mediafiles which contain only one audio
   stream! The only allowed options are -v --ss --t --to. Do not use
   any further options.

8. Recreate PTS (-p).

   To recreate the pts do:

   mediapts <infile> <outfile>

   Use the function with mediafiles which contain only one H264 encoded
   video stream and one audio stream! The only allowed options are -v
   -q --adur --probs. Do not use any further options.

9. Split an MP4 into chunks of equal duration (-S)

   To split the MP4 in chunks of 30 minutes do:

   mediasplit --st=00:30:00 <infile>

COMPANDER
To select a compander profile give it's number to --compand=

1)	An example for audio with whisper and explosion parts:

	compand=0|0:1|1:-90/-900|-70/-70|-30/-9|0/-3:6:0:0:0

2)	Make music with both quiet and loud passages suitable for
	listening to in a noisy environment:

	compand=.3|.3:1|1:-90/-60|-60/-40|-40/-30|-20/-20:6:0:-90:0.2

3)	Trim audio stream of a video to Integrated Loudness of -16dB
	and apply light dynamic range compression. If clipping occurs
	then use (13) Hard limiter at -3dB for the clipped file:

	compand=.3|.3:1|1:-90/-60|-60/-40|-40/-30|-30/-20|-16/-16|
	0/-3:6:0:-90:0.2

4)	A noise gate for when the noise is at a lower level than the
	signal:

	compand=.1|.1:.2|.2:-900/-900|-50.1/-900|-50/-50:.01:0:-90:.1

5)	Here is another noise gate, this time for when the noise is at
	a higher level than the signal (making it, in some ways,
	similar to squelch):

	compand=.1|.1:.1|.1:-45.1/-45.1|-45/-900|0/-900:.01:45:-90:.1

6)	2:1 compression starting at -6dB:

	compand=points=-80/-80|-6/-6|0/-3.8|20/3.5

7)	2:1 compression starting at -9dB:

	compand=points=-80/-80|-9/-9|0/-5.3|20/2.9

8)	2:1 compression starting at -12dB:

	compand=points=-80/-80|-12/-12|0/-6.8|20/1.9

9)	2:1 compression starting at -18dB:

	compand=points=-80/-80|-18/-18|0/-9.8|20/0.7

10)	3:1 compression starting at -15dB:

	compand=points=-80/-80|-15/-15|0/-10.8|20/-5.2

11)	Compressor/Gate:

	compand=points=-80/-105|-62/-80|-15.4/-15.4|0/-12|20/-7.6

12)	Expander:

	compand=attacks=0:points=-80/-169|-54/-80|-49.5/-64.6|
	-41.1/-41.1|-25.8/-15|-10.8/-4.5|0/0|20/8.3

13)	Hard limiter at -3dB:

	compand=attacks=0:points=-80/-80|-3/-3|20/-3

14)	Hard limiter at -6dB:

	compand=attacks=0:points=-80/-80|-6/-6|20/-6

15)	Hard limiter at -12dB:

	compand=attacks=0:points=-80/-80|-12/-12|20/-12

16)	Hard noise gate at -35 dB:

	compand=attacks=0:points=-80/-115|-35.1/-80|-35/-35|20/20

17)	Soft limiter:

	compand=attacks=0:points=-80/-80|-12.4/-12.4|-6/-8|0/-6.8|
	20/-2.8

Defaults:  Transcode media files to other formats.

OPTIONS
Gnu style options:

  Main options:

  -h|--help     = Output help, then exit.
  -V|--version  = Output version info, then exit.
  -d|--debug    = Turn on DEBUG mode.
  --d1          = Turn on DEBUG1 mode for ffmpeg cmdline, then exit.
  -q|--quiet    = Be quiet.
  -v|--verbose  = Be verbose.
  -a            = Get audio stream info about infile.
                  Show channel layout for 5.1 and 5.1(side).
  -c            = Extract part of a media file.
  -f            = Get volume info about infile.
  -g            = Show volume graphics.
  -i            = Get info about infile.
  -p            = Recreate PTS.
  -S            = Split MP4 into chunks (def. 00:15:00).
                  Give chunk size with --st
  --tp          = Use True Peak instead of Sample Peak (command -f).
  --vold        = Use volumedetect instead of ebu_r128 (command -f).
  -w            = Extract audio as wave file.

  FFmpeg options:

  --ab=abrate   = Audio bit rate.
  --ac=achans   = Audio channels for downmix and upmix.
  --acodec=acod = Audio codec.
  --vcodec=vcod = Video codec.
  --an          = No audio recording.
  --adur=and    = Analyzeduration (input).
  --ar=asrate   = Audio sampling frequency.
  --asetpts     = Set the pts for audio.
  --aspect=asp  = Set aspect ratio.
  --compand=cmp = Select a compander profile to use.
  --crf=crfq    = Set quality for h264 (Constant Rate Factor).
  --fflags=flag = Set formatflags.
  --mapa=strm   = Map audio stream <strm> from infile to outfile.
  --mapv=strm   = Map video stream <strm> from infile to outfile.
  --norm        = Use dynaudnorm.
  --pixfmt=pixf = Set pixel format.
  --probs=psize = Probesize (input).
  --qscale=q    = Set quality for VBR.
  --r=rate      = Video frame rate/sec.
  --s=size      = Video frame Size.
  --setpts      = Set the pts for video.
  --srepl=repl  = SPACE replacement (may use it in --extrai, --extrao).
  --ss=start    = Start at time (output option).
  --ssi=start   = Start at time (input option).
  --st=dur      = Segment time for file split.
  --t=dur       = Duration (output option). Give only --t or --to.
  --to=end      = End at time (output option). Give only --t or --to.
  --target=targ = Target.
  --timestamp   = Set start of timestamp to 00:00:00.00 (for record).
  --vn          = No video recording.
  --volume=vol  = Adjust volume.
  --vr=vrate    = Video bit rate/sec.
  --vsync=vsyn  = Video sync method.
  --extrai=xi   = Input options in ffmpeg format. Repl. SPACE with ','
  --extrao=xo   = Output options in ffmpeg format. Repl. SPACE with ','
  --            = End of options.

OPTION ARGUMENTS
Give if needed:

  abrate        = 192k|128k|..., (FFmpeg default = 64k)
  achans        = 2|6|..., (FFmpeg default = 1)
  acod          = copy|aac|ac3|mp2|mp3|..., (FFmpeg default = auto)
  and           = microseconds 100M|... (default = 5000000)
  asp           = 4:3|16:9
  asrate        = 48000|44100|..., (FFmpeg default = 44100)
  cmp           = Compander profile (1..17)
  crfq          = 0..51 (0=lossless,51=worst,def=23,17=visib. lossless)
  dur           = seconds|HH:MM:SS[.dec] (dec = 1 - 3 digits)
  end           = seconds|HH:MM:SS[.dec] (dec = 1 - 3 digits)
  flag          = +genpts
  infile        = Media Input file
  outfile       = Media Output file
  pixf          = +|... (+ = same fmt as input, s. man MPEG)
  psize         = Bytes 32 - n, 100M|... (default = 5000000)
  q             = 1..31 (quality for VBR, 1=excellent and 31=worst)
  rate          = 25|...
  repl          = Replacement for a SPACE (default = ',')
  size          = 720x576|svga|hd720|hd1080|..., (or WxH, look FFmpeg)
  start         = seconds|HH:MM:SS[.dec] (dec = 1 - 3 digits)
  strm          = 0:n (0=infile, n=stream)
  targ          = pal-dvd|..., (look at FFmpeg)
  vcod          = copy|mpeg4|mpeg2video|h264|..., (FFmpeg default=auto)
  vol           = inc: vol, dec: -vol (vol is seen as value in dB)
  vrate         = 64k|1500k|...
  vsyn          = passthrough|cfr|vfr|drop
  xi            = Input options in ffmpeg format
                  (replace SPACE with ',').
  xo            = Output options in ffmpeg format
                  (replace SPACE with ',').

EXAMPLES
For instance:

1. Transcode streams in container file test.flv to container file
   test.mp4 with recoding all streams. Use all default standards:

   media2media test.flv test.mp4

2. Transcode mpeg2 video stream 0:0 and audio stream 0:1 in container
   file test.ts to container file test.mp4. Use video codec h264 and
   audio codec aac. For all other options use default standards.
   To illustrate use of spacereplacement we generate timestamps with
   the default srepl ','  --->  --extrai=-fflags,+genpts
   If the ',' is needed in an ffmpeg option then we can select another
   char (a '|' f.i.) with --srepl=|

   media2media --extrai=-fflags,+genpts --mapv=0:0 --mapa=0:1
     --vcodec=h264 --acodec=aac test.ts test.mp4

3. Transcode streams in container file test.wmv to container file
   test.mp4 with recoding all video and audio streams. Set size of
   video to 800x600 (svga). Set audio codec to aac, audio sampling
   frequency to 44100 Hz, audio bit rate to 128 kb/s.

   media2media --vcodec=mpeg4 --s=svga --acodec=aac --ar=44100
     --ab=128k test.wmv test.mp4

4. Extract the 2 channel audio stream from container file test.flv as
   wav:

   media2wav test.flv [test.wav]

5. Extract part of container file test.mp4 to new.mp4. Start at
   00:1:30.4 for a duration of 2 minutes. Times can be given in seconds
   or in HH:MM:SS[.ss] format:

   1. mediacut --ss=00:01:30.4 --t=00:02:00 test.mp4 new.mp4
   2. mediacut --ss=90.4 --t=120 test.mp4 new.mp4

6. Raise the volume level by 6dB from file test.mp4. Output goes to
   new.mp4:
   media2media --volume=6 --vcodec=copy --acodec=aac test.mp4 new.mp4

   This is better done with mediafilter-volume

7. Remove Peak values above -3dB:
   media2media --compand=13 --vcodec=copy --acodec=aac test.mp4 new.mp4

   This is better done with mediafilter-compand

EXIT STATUS
On program exit:

  Code 0 = OK

  See output of 'showerrmsg'.

FILES
Used directories and files:

  Config Global = /usr/local/etc/multimedia.conf
  Config User   = ~/.multimediarc

SEE ALSO
Related manpages:

  showerrmsg(1), ffmpeg(1), ffprobe(1), ffplay(1), MPEG(7),
  media2media(1), media2wav(1), mediachannel-info(1), mediaconcat(1),
  mediacut(1), mediademux(1), mediafilter-compand(1),
  mediafilter-dolby-volcomp(1), mediafilter-dolby-volume(1),
  mediafilter-dynaudnorm(1), mediafilter-equalizer(1),
  mediafilter-volcomp(1), mediafilter-volume(1), mediainfo(1),
  mediajpegs2video(1), medialcut(1), mediamux(1), mediapts(1),
  mediashow-frames(1), mediasplit(1), mediasplit5.1(1), mediatitle(1),
  mediatxt2video(1), mediavolinfo(1), mediavolshow(1),
  audiofilter-compand(1), audiofilter-dynaudnorm(1),
  audiofilter-dynvol(1), audiofilter-fade(1), audiofilter-limiter(1),
  audiofilter-tempo(1), audiofilter-volcomp(1), audiofilter-volume(1),
  audiolayout(1), audiovolinfo(1), audiovolman(1).

AUTHORS
Juergen Kaesmann <juergen@kaesmann-online.de>
EOT
#  -o|--output  = Output to STDOUT.
#  -i f         = Input from file <f>.
#  --infile=f   = Input from file <f>.
#  -o f         = Output to file <f>.
#  --outfile=f  = Output to file <f>.
#  -p s,e       = Pages s=START e=END.
#  --pages=s,e  = Pages s=START e=END.

return
}

#=============================================================================
function select_compander ()
{
# Select a compand filter rule/profile
# par1 = number of profile
# Uses echo, logger
# Output is returned in global var 'compand'
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG select_compander: $# $@" >&2
	$debuglog select_compander: $# $@
fi

local n="$1" ret=0


case "$n" in
    1)	# An example for audio with whisper and explosion parts:
	compand='-af compand=0|0:1|1:-90/-900|-70/-70|-30/-9|0/-3:6:0:0:0'
	;;
    2)	# Make music with both quiet and loud passages suitable for listening
	# to in a noisy environment:
	compand='-af compand=.3|.3:1|1:-90/-60|-60/-40|-40/-30|-20/-20:6:0:-90:0.2'
	;;
    3)	# Trim audio stream of a video to Integrated Loudness of -16dB and
	# apply light dynamic range compression:
	compand='-af compand=.3|.3:1|1:-90/-60|-60/-40|-40/-30|-30/-20|-16/-16|0/-3:6:0:-90:0.2'
	;;
    4)	# A noise gate for when the noise is at a lower level than the
	# signal:
	compand='-af compand=.1|.1:.2|.2:-900/-900|-50.1/-900|-50/-50:.01:0:-90:.1'
	;;
    5)	# Here is another noise gate, this time for when the noise is at a
	# higher level than the signal (making it, in some ways, similar to
	# squelch):
	compand='-af compand=.1|.1:.1|.1:-45.1/-45.1|-45/-900|0/-900:.01:45:-90:.1'
	;;
    6)	# 2:1 compression starting at -6dB:
	compand='-af compand=points=-80/-80|-6/-6|0/-3.8|20/3.5'
	;;
    7)	# 2:1 compression starting at -9dB:
	compand='-af compand=points=-80/-80|-9/-9|0/-5.3|20/2.9'
	;;
    8)	# 2:1 compression starting at -12dB:
	compand='-af compand=points=-80/-80|-12/-12|0/-6.8|20/1.9'
	;;
    9)	# 2:1 compression starting at -18dB:
	compand='-af compand=points=-80/-80|-18/-18|0/-9.8|20/0.7'
	;;
    10)	# 3:1 compression starting at -15dB:
	compand='-af compand=points=-80/-80|-15/-15|0/-10.8|20/-5.2'
	;;
    11)	# Compressor/Gate at 15.4dB:
	compand='-af compand=points=-80/-105|-62/-80|-15.4/-15.4|0/-12|20/-7.6'
	;;
    12)	# Expander:
	compand='-af compand=attacks=0:points=-80/-169|-54/-80|-49.5/-64.6|-41.1/-41.1|-25.8/-15|-10.8/-4.5|0/0|20/8.3'
	;;
    13)	# Hard limiter at -3dB:
	compand='-af compand=attacks=0:points=-80/-80|-3/-3|20/-3'
	;;
    14)	# Hard limiter at -6dB:
	compand='-af compand=attacks=0:points=-80/-80|-6/-6|20/-6'
	;;
    15)	# Hard limiter at -12dB:
	compand='-af compand=attacks=0:points=-80/-80|-12/-12|20/-12'
	;;
    16)	# Hard noise gate at -35 dB:
	compand='-af compand=attacks=0:points=-80/-115|-35.1/-80|-35/-35|20/20'
	;;
    17)	# Soft limiter:
	compand='-af compand=attacks=0:points=-80/-80|-12.4/-12.4|-6/-8|0/-6.8|20/-2.8'
	;;
    *)
	Show_Err 9 "option --compand $opt_compand"
	exit 9
	;;
esac

return $ret
}

#=============================================================================
function audio_layout ()
{
# Output audio infos about a media file.
# par1 = 
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG audio_layout: $# $@" >&2
	$debuglog audio_layout: $# $@
fi

local c="" s=""
local ret=0

# output only audio streams
s=$(ffprobe -hide_banner -v error -show_entries stream=channel_layout -of csv=p=0 $arg1)
ret=$?
if [ $ret -eq 0 ]; then
	for c in $s; do
		ffmpeg -v error -layouts | grep "$c "
		ret=$?
	done
	if [ "$ret" -ne 0 ]; then			# from ffmpeg
		Show_Err $ret "from ffmpeg/grep"
	fi
else
	if [ "$ret" -ne 0 ]; then			# from ffprobe
		Show_Err $ret "from ffprobe"
	fi

fi

return $ret
}

#=============================================================================
function media_cut ()
{
# Cut out a part of a mediafile.
# par1 = 
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG media_cut: $# $@" >&2
	$debuglog media_cut: $# $@
fi

local ext1='' ext2='' s=""
local ret=0

ext1=${arg1##*.}
ext2=${arg2##*.}
if [ $ext1 != $ext2 ]; then
	Show_Err 11 "Unequal extensions."
	exit 11
fi

opt_mapa="-map 0"				# map all streams
opt_acodec="-codec copy"			# copy all streams
	#echo "ffmpeg -hide_banner $opt_adur $opt_probs $opt_ssi -i $arg1 $opt_ss $opt_t $opt_to $opt_mapa $opt_acodec $opt_pixfmt $arg2"
case "$verbose" in
    yes)
	echo "Run $scriptname"
	ffmpeg $opt_adur $opt_probs $opt_ssi -i $arg1 $opt_ss $opt_t $opt_to $opt_mapa $opt_acodec $opt_pixfmt $arg2
	ret=$?
	;;
    '')
	#echo "Run $scriptname"
	s=y
	if [ -e "$arg2" ]; then
		echo -n "Overwrite file (y/N)? "
		read s
	fi
	if [ "$s" == y ] || [ "$s" == Y ]; then
		ffmpeg -hide_banner -y $opt_adur $opt_probs $opt_ssi -i $arg1 $opt_ss $opt_t $opt_to $opt_mapa $opt_acodec $opt_pixfmt $arg2 2>/dev/null
		ret=$?
	fi
	;;
    no)
	ffmpeg -hide_banner -y $opt_adur $opt_probs $opt_ssi -i $arg1 $opt_ss $opt_t $opt_to $opt_mapa $opt_acodec $opt_pixfmt $arg2 &>/dev/null
	ret=$?
	;;
esac
if [ "$ret" -ne 0 ]; then				# for other progs
	Show_Err ${_ERR_GENERAL_} "$ret from ffmpeg"
	ret=${_ERR_GENERAL_}
fi

return $ret
}

#=============================================================================
function media_volinfo ()
{
# Give a volume statistic about a mediafile.
# par1 = 
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG media_volinfo: $# $@" >&2
	$debuglog media_volinfo: $# $@
fi

local ret=0

if [ -z "$opt_vold" ]; then
	if [ -z "$opt_tp" ]; then
		#ffmpeg -hide_banner -nostats -i $arg1 -vn -filter_complex [0:a]ebur128=peak=sample -f null -
		ffmpeg -hide_banner -nostats -i $arg1 -vn -filter_complex [0:a]ebur128=peak=sample -f null -
		ret=$?
	else
		#ffmpeg -hide_banner -nostats -i $arg1 -vn -filter_complex [0:a]ebur128=peak=true -f null -
		ffmpeg -hide_banner -nostats -i $arg1 -vn -filter_complex [0:a]ebur128=peak=true -f null -
		ret=$?
	fi
else
	#ffmpeg -hide_banner -i $arg1 -af "volumedetect" -vn -sn -dn -f null /dev/null
	ffmpeg -hide_banner -i $arg1 -af "volumedetect" -vn -sn -dn -f null /dev/null
	ret=$?
fi
if [ "$ret" -ne 0 ]; then				# for other progs
	Show_Err ${_ERR_GENERAL_} "$ret from ffmpeg"
	ret=${_ERR_GENERAL_}
fi

return $ret
}

#=============================================================================
function media_volshow ()
{
# Show a window with volume statistics.
# par1 = 
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG media_volshow: $# $@" >&2
	$debuglog media_volshow: $# $@
fi

local found=no
local ret=0

tempmf="${tempmf}.${arg1##*.}"

if [ -n "$opt_ss" ]; then found=yes; fi
if [ -n "$opt_t" ]; then found=yes; fi
if [ -n "$opt_to" ]; then found=yes; fi

if [ $found == yes ]; then
	opt_mapa="-map 0"				# map all streams
	opt_acodec="-codec copy"			# copy all streams
	ffmpeg -hide_banner -i $arg1 $opt_ss $opt_t $opt_to $opt_mapa $opt_acodec $tempmf
	ret=$?
	arg1=$tempmf
	if [ "$ret" -ne 0 ]; then
		Show_Err ${_ERR_GENERAL_} "$ret from ffmpeg"
		ret=${_ERR_GENERAL_}
	fi
fi

if [ "$ret" -eq 0 ]; then
	# Real-time graph using ffplay, with a EBU scale meter +18:
	ffplay -hide_banner -f lavfi -i "amovie=${arg1},ebur128=video=1:size=900x600:peak=sample:meter=18 [out0][out1]"
	ret=$?
	if [ "$ret" -ne 0 ]; then
		Show_Err ${_ERR_GENERAL_} "$ret from ffplay"
		ret=${_ERR_GENERAL_}
	fi
fi

rm -f $tempmf

return $ret
}

#=============================================================================
function media_info ()
{
# Output infos about a media file.
# par1 = 
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG media_info: $# $@" >&2
	$debuglog media_info: $# $@
fi

local ret=0

# use ffprobe instead of ffmpeg
case "$verbose" in
    yes)					# allow STDOUT and STDERR
	echo "Run $scriptname"
	ffprobe -v error -hide_banner $opt_adur $opt_probs $arg1 -show_streams
	ret=$?
	;;
    '')						# suppress STDERR
	#echo "Run $scriptname"
	ffprobe -hide_banner $opt_adur $opt_probs $arg1 -show_entries stream=index,codec_type,start_time,duration -of compact #2>/dev/null
	ret=$?
	;;
    no)						# suppress STDOUT and STDERR
	ffprobe -hide_banner $opt_adur $opt_probs $arg1 -show_entries stream=index,codec_type,start_time,duration -of compact &>/dev/null
	ret=$?
	;;
esac
if [ "$ret" -ne 0 ]; then				# from ffprobe
	Show_Err ${_ERR_GENERAL_} "$ret from ffprobe"
	ret=${_ERR_GENERAL_}
fi

return $ret
}

#=============================================================================
function media_split ()
{
# Split mp4 into chunks of 15 minutes
# par1 = 
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG media_split: $# $@" >&2
	$debuglog media_split: $# $@
fi

local presplit=splitter
local ret=0

if [ -z "$opt_st" ]; then
	opt_st=00:15:00
fi

rm -f ${presplit}*
case "$verbose" in
    yes)
	echo "Run $scriptname"
	ffmpeg -i $arg1 -c copy -map 0 -segment_time $opt_st -f segment -reset_timestamps 1 ${presplit}_%02d.mp4
	ret=$?
	;;
    '')
	#echo "Run $scriptname"
	ffmpeg -hide_banner -i $arg1 -c copy -map 0 -segment_time $opt_st -f segment -reset_timestamps 1 ${presplit}_%02d.mp4 2>/dev/null
	ret=$?
	;;
    no)
	ffmpeg -hide_banner -i $arg1 -c copy -map 0 -segment_time $opt_st -f segment -reset_timestamps 1 ${presplit}_%02d.mp4 &>/dev/null
	ret=$?
	;;
esac
if [ "$ret" -ne 0 ]; then				# for other progs
	Show_Err ${_ERR_GENERAL_} "$ret from ffmpeg"
	ret=${_ERR_GENERAL_}
fi

return $ret
}

#=============================================================================
function media_pts ()
{
# Recreate PTS
# par1 = 
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG media_pts: $# $@" >&2
	$debuglog media_pts: $# $@
fi

#local tmp264=${tempfile}.264				# for example 2
local ret=0

# example 1
case "$verbose" in
    yes)
	echo "Run $scriptname"
	ffmpeg -vsync drop -i $arg1 -map 0:v -vcodec copy -map 0:a -acodec copy $arg2
	ret=$?
	;;
    '')
	#echo "Run $scriptname"
	ffmpeg -hide_banner -y -vsync drop -i $arg1 -map 0:v -vcodec copy -map 0:a -acodec copy $arg2 2>/dev/null
	ret=$?
	;;
    no)
	ffmpeg -hide_banner -y -vsync drop -i $arg1 -map 0:v -vcodec copy -map 0:a -acodec copy $arg2 &>/dev/null
	ret=$?
	;;
esac
if [ "$ret" -ne 0 ]; then				# for other progs
	Show_Err ${_ERR_GENERAL_} "$ret from ffmpeg"
	ret=${_ERR_GENERAL_}
fi

# example 2
#ffmpeg -hide_banner -i $arg1 -map 0:v -vcodec copy -bsf:v h264_mp4toannexb $tmp264
#ret=$?
#ffmpeg -hide_banner -fflags +genpts -r 25 -i $tmp264 -vcodec copy $arg2
#ret=$?
#rm -f $tmp264

return $ret
}

#=============================================================================
function media_2wav ()
{
# Extract the audio stream of a media file.
# par1 = 
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG media_2wav: $# $@" >&2
	$debuglog media_2wav: $# $@
fi

local ext=${arg2##*.}
local ret=0

if [ "$ext" == wav ]; then
	opt_ac="-ac 2"					# set 2 audiochannels
	case "$verbose" in
	    yes)
		echo "Run $scriptname"
		ffmpeg -i $arg1 $opt_ac $arg2
		ret=$?
		;;
	    '')
		#echo "Run $scriptname"
		ffmpeg -hide_banner -y -i $arg1 $opt_ac $arg2 2>/dev/null
		ret=$?
		;;
	    no)
		ffmpeg -hide_banner -y -i $arg1 $opt_ac $arg2 &>/dev/null
		ret=$?
		;;
	esac
	if [ "$ret" -ne 0 ]; then			# for other progs
		Show_Err ${_ERR_GENERAL_} "$ret from ffmpeg"
		ret=${_ERR_GENERAL_}
	fi
else
	Show_Err ${_ERR_GENERAL_} "Outfile is not a wav file"
	ret=${_ERR_GENERAL_}
fi

return $ret
}

#=============================================================================
function mainproc ()
{
# process transcoding infile to outfile.
# par1 = infile
# par2 = outfile
# Uses echo, ffmpeg, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG main proc: $# $@" >&2
	$debuglog main proc: $# $@
fi

local inf="$1" outf="$2"
local ret=0
#local -a arr
#maxarr="${#arr[@]}"			# get number of elements in arr
#unset arr[@]				# remove the entire array

if [ "$debug1" == "yes" ]; then				# DEBUG
cat <<-EOT
ffmpeg $opt_adur $opt_probs $opt_vsync $opt_extrai $opt_fflags 
	$opt_ssi -i $inf $opt_ss $opt_t $opt_to $opt_timestamp $opt_mapv 
	$opt_mapa $opt_vcodec $opt_acodec $opt_target $opt_crf 
	$opt_vr $opt_r $opt_s $opt_pixfmt $opt_aspect $opt_qscale 
	$opt_ac $opt_volume $opt_compand $opt_norm $opt_setpts 
	$opt_asetpts $opt_ar $opt_ab $opt_vn $opt_an $opt_extrao $outf
EOT
	exit 98
fi

case "$verbose" in
    yes)
	echo "Run $scriptname $cmd"
	# allow STDOUT and STDERR
	ffmpeg $opt_adur $opt_probs $opt_vsync $opt_ssi $opt_extrai $opt_fflags \
		-i $inf $opt_ss $opt_t $opt_to $opt_timestamp $opt_mapv \
		$opt_mapa $opt_vcodec $opt_acodec $opt_target $opt_crf \
		$opt_vr $opt_r $opt_s $opt_pixfmt $opt_aspect $opt_qscale \
		$opt_ac $opt_volume $opt_compand $opt_norm $opt_setpts \
		$opt_asetpts $opt_ar $opt_ab $opt_vn $opt_an $opt_extrao $outf
	ret=$?
	;;
    '')
	#echo "Run $scriptname $cmd"
	# allow STDOUT or STDERR
	ffmpeg -hide_banner $opt_adur $opt_probs $opt_vsync $opt_extrai $opt_fflags \
		$opt_ssi -i $inf $opt_ss $opt_t $opt_to $opt_timestamp $opt_mapv \
		$opt_mapa $opt_vcodec $opt_acodec $opt_target $opt_crf \
		$opt_vr $opt_r $opt_s $opt_pixfmt $opt_aspect $opt_qscale \
		$opt_ac $opt_volume $opt_compand $opt_norm $opt_setpts \
		$opt_asetpts $opt_ar $opt_ab $opt_vn $opt_an $opt_extrao $outf
	#1>/dev/null
	#2>/dev/null
	ret=$?
	;;
    no)
	# suppress STDOUT and STDERR
	ffmpeg -hide_banner -y $opt_adur $opt_probs $opt_vsync $opt_extrai $opt_fflags \
		$opt_ssi -i $inf $opt_ss $opt_t $opt_to $opt_timestamp $opt_mapv \
		$opt_mapa $opt_vcodec $opt_acodec $opt_target $opt_crf \
		$opt_vr $opt_r $opt_s $opt_pixfmt $opt_aspect $opt_qscale \
		$opt_ac $opt_volume $opt_compand $opt_norm $opt_setpts \
		$opt_asetpts $opt_ar $opt_ab $opt_vn $opt_an $opt_extrao $outf &>/dev/null
	#&>/dev/null
	ret=$?
	;;
esac
if [ "$ret" -ne 0 ]; then				# for other progs
	Show_Err ${_ERR_GENERAL_} "$ret from ffmpeg"
	ret=${_ERR_GENERAL_}
fi

return $ret
}

##############################################################################
# GET OPTIONS
##############################################################################
# Give 2 strings and all cmdline_args to func Get Opt
# (POSIX_options Gnu_long_options cmdline_args):
# Get Opt 'hVdqvi:m:' 'help version debug quiet verbose infile= myval=' $@
#
# A ':' after a POSIX option means this option needs an arg.
# A '=' after a Gnu long option means this option needs an arg.
#
# All cmd/options have to be initialised to ''!
#
# POSIX options are classified in 2 categories:
#   a) cmds (mutually exclusive). All cmds are given to var 'cmd'.
#   b) options (as many as you like). Each option is given to it's own var.
# As a general rule: If cmds/options are given multiple then last given wins.
#
# Options can take 1 argument (no whitespace in arg). If you want to give more
# than 1 arg or want to use multiple strings as 1 arg then concatenate them
# together with a delimiter like ',' or ';' or '.'
# Use a delimiter which will not be part of the arg:
# sampleprog -m val1,val2
# sampleprog --myval=val1,val2
# It's at the programmers responsibility to do meaningfull things with the
# content of the options.
#
# If err != 0 then all args are processed, else continue to look for options.
# When Get Opt finishes then all options are removed from cmdline.
#
if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG Parse Commandline: $# $@" >&2
	$debuglog Parse Commandline: $# $@
fi
#
err=0
while [ "$err" -eq 0 ]; do
	GetOpt 'hVdqvacfgipSw' 'help version debug d1 quiet verbose ab= ac= acodec= adur= an ar= asetpts aspect= compand= crf= extrai= extrao= fflags= mapv= mapa= norm pixfmt= probs= qscale= r= s= setpts srepl= ss= ssi= st= t= target= timestamp tp to= vcodec= vold vn volume= vr= vsync=' $@
	err=$?
	if [ $err -eq 0 ]; then
		case "$_OPTNAME_" in
		    h|help)	cmd="-h";;
		    V|version)	cmd="-V";;
		    a)		cmd="-${_OPTNAME_}";;
		    c)		cmd="-${_OPTNAME_}";;
		    f)		cmd="-${_OPTNAME_}";;
		    g)		cmd="-${_OPTNAME_}";;
		    i)		cmd="-${_OPTNAME_}";;
		    p)		cmd="-${_OPTNAME_}";;
		    S)		cmd="-${_OPTNAME_}";;
		    w)		cmd="-${_OPTNAME_}";;
		    d|debug)	debug=yes;;
		    d1)		debug1=yes;;
		    q|quiet)	verbose=no;;
		    v|verbose)	verbose=yes;;
		    vold)	opt_vold=yes;;
		    tp)		opt_tp=yes;;
#		    o|output)	opt_o=yes;;
#		    i|infile)	opt_i="${_OPTVAL_}";;
#		    o|outfile)	opt_o="${_OPTVAL_}";;
#		    p|pages)	opt_p="${_OPTVAL_}";;
		    ab)		opt_ab="-ab $_OPTVAL_";;
		    ac)		opt_ac="-ac $_OPTVAL_";;
		    acodec)	opt_acodec="-acodec $_OPTVAL_";;
		    adur)	opt_adur="-analyzeduration $_OPTVAL_";;
		    an)		opt_an="-an";;
		    ar)		opt_ar="-ar $_OPTVAL_";;
		    asetpts)	opt_asetpts="-filter:a atrim -filter:a asetpts=PTS-STARTPTS";;
		    aspect)	opt_aspect="-aspect $_OPTVAL_";;
		    compand)	opt_compand="$_OPTVAL_";;
		    crf)	opt_crf="-crf $_OPTVAL_";;
		    fflags)	opt_fflags="-fflags $_OPTVAL_";;
		    mapa)	opt_mapa="-map $_OPTVAL_";;
		    mapv)	opt_mapv="-map $_OPTVAL_";;
		    norm)	opt_norm="-af dynaudnorm";;
		    pixfmt)	opt_pixfmt="-pix_fmt $_OPTVAL_";;
		    probs)	opt_probs="-probesize $_OPTVAL_";;
		    qscale)	opt_qscale="-q:v $_OPTVAL_";;
		    r)		opt_r="-r $_OPTVAL_";;
		    s)		opt_s="-s $_OPTVAL_";;
		    setpts)	opt_setpts="-filter:v trim -filter:v setpts=PTS-STARTPTS";;
		    srepl)	opt_srepl="$_OPTVAL_";;
		    ss)		opt_ss="-ss $_OPTVAL_";;
		    ssi)	opt_ssi="-ss $_OPTVAL_";;
		    st)		opt_st="$_OPTVAL_";;
		    t)		opt_t="-t $_OPTVAL_";;
		    target)	opt_target="-target $_OPTVAL_";;
		    timestamp)	opt_timestamp="-timestamp 00:00:00";;
		    to)		opt_to="-to $_OPTVAL_";;
		    vcodec)	opt_vcodec="-vcodec $_OPTVAL_";;
		    vn)		opt_vn="-vn";;
		    volume)	opt_volume="-filter:a volume=${_OPTVAL_}dB";;
		    vr)		opt_vr="-b:v $_OPTVAL_";;
		    vsync)	opt_vsync="-vsync $_OPTVAL_";;
		    extrai)	opt_extrai="$_OPTVAL_";;
		    extrao)	opt_extrao="$_OPTVAL_";;
		    --)		break;;
		    :)	Show_Err ${_ERR_MISSING_ARG_FOR_OPT_} "-${_OPTVAL_}"
			exit ${_ERR_MISSING_ARG_FOR_OPT_};;
		    ?)	Show_Err ${_ERR_UNKNOWN_OPT_} "-${_OPTVAL_}"
			exit ${_ERR_UNKNOWN_OPT_};;
		    *)	Show_Err ${_ERR_UNKNOWN_ERR_} "_OPTNAME_=${_OPTNAME_} _OPTVAL_=${_OPTVAL_}"
			exit ${_ERR_UNKNOWN_ERR_};;
		esac
	fi
done
err=0
shift ${_OPTIDX_}				# rm all opts from cmdline
#
#if [ -z "$cmd" ]; then					# error no cmd given
#	Show_Err 7 ""
#	exit 7
#fi

##############################################################################
# CHECK LINK NAMES
#
if [ "$cmd" != "-h" ] && [ "$cmd" != "-V" ]; then
	case "$scriptname" in
	    audiolayout)
		cmd="-a"
		;;
	    media2wav)
		cmd="-w"
		;;
	    mediacut)
		cmd="-c"
		;;
	    mediainfo)
		cmd="-i"
		;;
	    mediapts)
		cmd="-p"
		;;
	    mediasplit)
		cmd="-S"
		;;
	    mediavolinfo)
		cmd="-f"
		;;
	    mediavolshow)
		cmd="-g"
		;;
	esac
fi

##############################################################################
# CHECK OPTIONS
#
#-----------------------------------------------------------------------------
# check not allowed options for sub commands
#case "$cmd" in
#    -l|-p)						# for these cmds
#	if [ -n "$opt_z" ]; then			# option -z not allowed
#		Show_Err 13 "-z"
#		exit 13
#	fi
#	;;
#    *)							# for all other cmds
#	:
#	;;
#esac
#
#-----------------------------------------------------------------------------
# check allowed options for sub commands
if [ -n "$opt_vold" ]; then
	case "$cmd" in
	    -f)						# option --vold allowed
		:
		;;
	    *)						# for all other cmds
#		Show_Err 13 "--tp"
		exit 13
		;;
	esac
fi
if [ -n "$opt_tp" ]; then
	case "$cmd" in
	    -f)						# option --tp allowed
		:
		;;
	    *)						# for all other cmds
#		Show_Err 13 "--tp"
		exit 13
		;;
	esac
fi
#
#-----------------------------------------------------------------------------
# check needed options for sub commands
#case "$cmd" in
#    -l|-p)						# for these cmds
#	if [ -z "$opt_z" ]; then			# option -z needed
#		Show_Err 8 "-z"
#		exit 8
#	fi
#	;;
#    *)							# for all other cmds
#	:
#	;;
#esac
#
#-----------------------------------------------------------------------------
# check options which are mutually exclusive
if [ -n "$opt_t" ] && [ -n "$opt_to" ]; then		# don't give both opts
		Show_Err 13 "${opt_t} and ${opt_to}"
		exit 13
fi
#
#-----------------------------------------------------------------------------
# check options which needs another option or cmd
if [ -n "$opt_st" ]; then			# opt_st given
	if [ "$cmd" != -S ]; then		# error - opt_st needs cmd -S
		Show_Err 1 "opt_st needs cmd -S"
		exit 1
	fi
fi
#
#-----------------------------------------------------------------------------
# get values from arg of option -p to vars p_first p_last
#if [ -n "$opt_p" ]; then
#	p_first="${opt_p%,*}"
#	p_last="${opt_p#*,}"
#fi
#
#-----------------------------------------------------------------------------
# set compander from val of opt_compand
if [ -n "$opt_compand" ]; then
	select_compander "$opt_compand"
	opt_compand="$compand"
fi
#
#-----------------------------------------------------------------------------
# setup values from arg of options extrai and extrao
if [ -n "$opt_extrai" ]; then
	opt_extrai=${opt_extrai//$opt_srepl/ }
fi
if [ -n "$opt_extrao" ]; then
	opt_extrao=${opt_extrao//$opt_srepl/ }
fi

##############################################################################
# CHECK VERSION

##############################################################################
# CHECK ARGUMENTS
#
case "$cmd" in
    ''|-c|-p)
	if [ "$#" -eq 2 ]; then				# parameter count ok
		arg1="$1"
		arg2="$2"
		shift 2
		#args="$@"
		#shift $#
	else						# error in param count
		Show_Err 2 ""
		exit 2
	fi
	;;
    -a|-f|-g|-i|-S)
	if [ "$#" -eq 1 ]; then				# parameter count ok
		arg1="$1"
		shift
	else						# error in param count
		Show_Err 2 ""
		exit 2
	fi
	;;
    -w)
	if [ "$#" -eq 1 ]; then				# parameter count ok
		arg1="$1"
		shift
		stemp=`basename $arg1`
		stemp="${stemp%.*}"
		arg2="${stemp}.wav"			# set 2. arg
	elif [ "$#" -eq 2 ]; then			# parameter count ok
		arg1="$1"
		arg2="$2"
		shift 2
	else						# error in param count
		Show_Err 2 ""
		exit 2
	fi
	opt_ac="-ac 2"
	;;
    *)
	if [ "$#" -ne 0 ]; then				# error in param count
		Show_Err 2 ""
		exit 2
	fi
	;;
esac

##############################################################################
# LOCK

##############################################################################
# MAINPROGRAM
##############################################################################
#
if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG Main: $# $@" >&2
	$debuglog Main: $# $@
fi

# Check what to do (sub commands, options and args are removed from cmdline)
case "$cmd" in
    '')
	mainproc $arg1 $arg2
	err=$?
	;;
    -h)
	helptext
	exit 0
	;;
    -V)
	echo "$scriptname (${package}) ${version}-${release}"
	exit 0
	;;
    -a)
	audio_layout
	err=$?
	;;
    -c)
	media_cut
	err=$?
	;;
    -f)
	media_volinfo
	err=$?
	;;
    -g)
	media_volshow
	err=$?
	;;
    -i)
	media_info
	err=$?
	;;
    -p)
	media_pts
	err=$?
	;;
    -S)
	media_split
	err=$?
	;;
    -w)
	media_2wav
	err=$?
	;;
    *)							# error
	Show_Err 6 ""
	err=6
	;;
esac

#rm -f $lockfile

exit $err
