Skip to content

Commit 1d4a67d

Browse files
authored
Merge branch 'master' into makelossless-updates
2 parents 7694708 + e30f0a9 commit 1d4a67d

18 files changed

+587
-148
lines changed

README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ set this variable to the directory where your youtube access copy is delivered.
162162
set this variable to a temporary directory. it is used in the uploadomneon microservice as a temporary place for a file to live before it is uploaded to the omneon server.
163163

164164
**10. REGEX4PODCAST**
165-
this varible holds regular expressions that are queried when makepodcast is run, in order to determine if a file qualifies for podcast creation. If you want all of your files to qualify for podcast creation, enter a "." which matches (almost) any character. Learn more about [regex](https://en.wikipedia.org/wiki/Regular_expression).
165+
this variable holds regular expressions that are queried when makepodcast is run, in order to determine if a file qualifies for podcast creation. If you want all of your files to qualify for podcast creation, enter a "." which matches (almost) any character. Learn more about [regex](https://en.wikipedia.org/wiki/Regular_expression).
166166

167167
**11. DVDLABELPREFIX**
168168
this variable is for adding a set prefix to the filename for DVDs in makedvd. You may leave this variable blank if you do not want to have a prefix uniformly assigned.
@@ -201,7 +201,7 @@ This variable must be set to yes (Y) or no (N). If set to yes, volume will be ru
201201
This variable must be set to yes (Y) or no (N). If set to yes, database reporting for mm will be enabled.
202202

203203
**23. SQL_ERROR_EMAIL_TO**
204-
This can be set to include an email address to recieve error reports for database insertion.
204+
This can be set to include an email address to receive error reports for database insertion.
205205

206206
**24. PREMIS_PROFILE**
207207
Enter the login path information for the database here. (Use the output supplied by the createpremisdb script, or create your own using mysql_config_editor).
@@ -236,7 +236,7 @@ To finalize the database setup, run `mmconfig` (GUI mode) or `mmconfig -t` (CLI)
236236
### Database Backup
237237
MM includes a script for database backup. This can be either run manually or set up as an automated process. After configuring the backup script, running `dbbackup` will create a zipped backup in the chosen location. To automate this process use Brew Services. Typing `brew services start mm` will cause the db to be backed up automatically using the included plist file. By default, backups will occur daily at 2:00 AM.
238238

239-
To configure database backup use the command `dbbackup -e`. This will open the config file in a terminal editor. Set the neccessary variables to your desired values.
239+
To configure database backup use the command `dbbackup -e`. This will open the config file in a terminal editor. Set the necessary variables to your desired values.
240240

241241
***
242242

@@ -385,10 +385,10 @@ To view the specific ffmpeg encoding options for each file, view the sourcecode
385385
* Creates a frame md5 for video files in target package. Relies on package structure used in mm.
386386

387387
#### makeframes
388-
* makeframes creates 10 still images from a video file or package input. Your command will look like: makeframes [input]. To deliver still images to a specific directory, use this command `ingestfile -d [path/to/directory] [input]`.
388+
* makeframes creates 10 still images from a video file or package input. Your command will look like: `makeframes [input]`. To deliver still images to a specific directory, use this command `ingestfile -d [path/to/directory] [input]`.
389389

390390
#### makelossless
391-
* makelossless losslessly transcodes a video file or package input. Your command will look like this: makelossless [input].
391+
* makelossless losslessly transcodes a video file or package input. Your command will look like this: `makelossless [input]`.
392392
* if you would like to transcode using lossless jpeg2000 instead of ffv1 version 3, use option j. Your command will look like this: `makelossless -j [input]`.
393393
* if you want to run makelossless in "dry-run" mode, which means that the commands will be shown in the terminal but not run, use option n. Your command will look like this: `makelossless -n [input]`.
394394

audiotest

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/bin/bash
2+
3+
echo "Package Name,First Object File Name,Count of Object Files,Count of Image Files,integrated loudness,loudness range,true peak,threshold,\
4+
target_offset,cuny loudness adjustment,silent ranges,phase issues,interstitial,duration,samplerate,channels,codec,peak level ch1,peak level ch2,peak level diff,bitscope,dcoffset,flatfactor,peakcount,bwfmetaedit"
5+
while [[ "${@}" != "" ]] ; do
6+
PACKAGE="$1"
7+
shift
8+
FILECOUNT=$(find "${PACKAGE}/objects" -maxdepth 2 -type f ! -name .DS_Store | wc -l | sed 's/ //g')
9+
10+
find "${PACKAGE}/objects" -maxdepth 2 -type f ! -name .DS_Store | while read FILENAME ; do
11+
ffmpeg -nostdin -i "${FILENAME}" -vn -filter_complex "silencedetect,astats,loudnorm=print_format=json,agate=attack=0.01:release=0.01:ratio=9000,aphasemeter=r=0.2:video=0,ametadata=mode=print:key=lavfi.aphasemeter.phase:value=-0.18:function=less" -f null - 2>&1 | tr "\r" "\n" > /tmp/loud
12+
image_count=$(find "${PACKAGE}/metadata/depictions" -maxdepth 2 -type f ! -name .DS_Store | wc -l | sed 's/ //g')
13+
measured_I=$(cat /tmp/loud | grep "input_i" | awk -F\" '{print $4}')
14+
measured_LRA=$(cat /tmp/loud | grep "input_lra" | awk -F\" '{print $4}')
15+
measured_TP=$(cat /tmp/loud | grep "input_tp" | awk -F\" '{print $4}')
16+
measured_thresh=$(cat /tmp/loud | grep "input_thresh" | awk -F\" '{print $4}')
17+
target_offset=$(cat /tmp/loud | grep "target_offset" | awk -F\" '{print $4}')
18+
LOUD_ADJ=$(echo "($measured_I - -24)*-1" | bc)
19+
DURATION=$(ffprobe "$FILENAME" -show_entries format=duration -of default=nw=1:nk=1 2>/dev/null)
20+
SAMPLERATE=$(ffprobe "$FILENAME" -show_entries stream=sample_rate -of default=nw=1:nk=1 2>/dev/null)
21+
CHANNELS=$(ffprobe "$FILENAME" -show_entries stream=channels -of default=nw=1:nk=1 2>/dev/null)
22+
CODEC=$(ffprobe "$FILENAME" -show_entries stream=codec_name -of default=nw=1:nk=1 2>/dev/null)
23+
24+
PEAKLEVEL1=$(cat /tmp/loud | grep "Peak level dB:" | tail -n +1 | head -n 1 | cut -d ":" -f 2 | sed 's/ //g')
25+
PEAKLEVEL2=$(cat /tmp/loud | grep "Peak level dB:" | tail -n +2 | head -n 1 | cut -d ":" -f 2 | sed 's/ //g')
26+
PEAKLEVELDIFF=$(echo "scale=3; $PEAKLEVEL1 - $PEAKLEVEL2" | bc)
27+
28+
BITSCOPE=$(cat /tmp/loud | grep "Bit depth: " | tail -n +3 | head -n 1 | cut -d ":" -f 2 | sed 's/ //g')
29+
DCOFFSET=$(cat /tmp/loud | grep "DC offset: " | tail -n +3 | head -n 1 | cut -d ":" -f 2 | sed 's/ //g')
30+
FLATFACTOR=$(cat /tmp/loud | grep "Flat factor: " | tail -n +3 | head -n 1 | cut -d ":" -f 2 | sed 's/ //g')
31+
PEAKCOUNT=$(cat /tmp/loud | grep "Peak count: " | tail -n +3 | head -n 1 | cut -d ":" -f 2 | sed 's/ //g')
32+
33+
bwfmetaedit=$(bwfmetaedit "$FILENAME" 2>&1 | awk '{printf "%s+",$0} END {print ""}')
34+
35+
SILENCE=$(cat /tmp/loud | grep " silence_end: " | while read line ; do
36+
silence_duration=$(echo "$line" | awk '{print $8}')
37+
silence_end=$(echo "$line" | awk '{print $5}')
38+
echo -n "$silence_end ($silence_duration);"
39+
done)
40+
41+
PHASEERROR=$(grep Parsed_ametadata /tmp/loud | paste - - | sed "s/lavfi.aphasemeter.phase=//g" | cut -d ":" -f 4 | awk '{print $1 "(" $5 ")"}' | xargs)
42+
INTERSTITIAL=$(ffprobe -f lavfi -i "amovie=${FILENAME},loudnorm=tp=0,astats=metadata=1:reset=1" -show_entries frame=pkt_pts_time:frame_tags=lavfi.astats.Overall.Max_difference -of csv 2>/dev/null | awk -F "," '$3>=0.07' | awk -F "," '{print $2 "(" $3 ")"}' | xargs)
43+
44+
echo "$(basename "$PACKAGE"),$(basename "$FILENAME"),$FILECOUNT,$image_count,$measured_I,$measured_LRA,$measured_TP,$measured_thresh,$target_offset,$LOUD_ADJ,$SILENCE,$PHASEERROR,$INTERSTITIAL,$DURATION,$SAMPLERATE,$CHANNELS,$CODEC,$PEAKLEVEL1,$PEAKLEVEL2,$PEAKLEVELDIFF,$BITSCOPE,$DCOFFSET,$FLATFACTOR,$PEAKCOUNT,$bwfmetaedit"
45+
done
46+
done

checksumpackage

+6-6
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ _check_dfxml(){
6464
PACKAGE="${ABS_PATH}"
6565
# make temp file that lists filenames and filesizes from dfxml.xml
6666
DFXML_FILELIST="$(_maketemp)"
67-
if [ ! -z "$(xml sel -T -t -m "/_:dfxml/_:fileobject" -v "_:filename" -o " " -v "_:filesize" -n "${PACKAGE}/${OUTDIR}/${DFXMLNAME}" 2>/dev/null)" ] ; then
68-
xml sel -T -t -m "/_:dfxml/_:fileobject" -v "_:filename" -o " " -v "_:filesize" -n "${PACKAGE}/${OUTDIR}/${DFXMLNAME}" | sort > "${DFXML_FILELIST}"
67+
if [ ! -z "$(xmlstarlet sel -T -t -m "/_:dfxml/_:fileobject" -v "_:filename" -o " " -v "_:filesize" -n "${PACKAGE}/${OUTDIR}/${DFXMLNAME}" 2>/dev/null)" ] ; then
68+
xmlstarlet sel -T -t -m "/_:dfxml/_:fileobject" -v "_:filename" -o " " -v "_:filesize" -n "${PACKAGE}/${OUTDIR}/${DFXMLNAME}" | sort > "${DFXML_FILELIST}"
6969
else
70-
xml sel -T -t -m "/dfxml/fileobject" -v "filename" -o " " -v "filesize" -n "${PACKAGE}/${OUTDIR}/${DFXMLNAME}" | sort > "${DFXML_FILELIST}"
70+
xmlstarlet sel -T -t -m "/dfxml/fileobject" -v "filename" -o " " -v "filesize" -n "${PACKAGE}/${OUTDIR}/${DFXMLNAME}" | sort > "${DFXML_FILELIST}"
7171
fi
7272
PWD=$(pwd)
7373
# make temp file that lists filenames and filesizes from current objects directory
@@ -177,10 +177,10 @@ while [ "${*}" != "" ] ; do
177177
_version_dfxml "${PACKAGE}"
178178
fi
179179
cat "${DFXMLTMP}" > "${PACKAGE}/${OUTDIR}/${DFXMLNAME}"
180-
if [ ! -z "$(xml sel -T -t -m "/_:dfxml/_:fileobject" -v "_:filename" -o " " -v "_:filesize" -n "${PACKAGE}/${OUTDIR}/${DFXMLNAME}" 2>/dev/null)" ] ; then
181-
xml sel -T -t -m "/_:dfxml/_:fileobject" -v "_:hashdigest" -o " " -v "_:filename" -n "${PACKAGE}/${OUTDIR}/${DFXMLNAME}" > "${PACKAGE}/${OUTDIR}/${CHECKSUMNAME}"
180+
if [ ! -z "$(xmlstarlet sel -T -t -m "/_:dfxml/_:fileobject" -v "_:filename" -o " " -v "_:filesize" -n "${PACKAGE}/${OUTDIR}/${DFXMLNAME}" 2>/dev/null)" ] ; then
181+
xmlstarlet sel -T -t -m "/_:dfxml/_:fileobject" -v "_:hashdigest" -o " " -v "_:filename" -n "${PACKAGE}/${OUTDIR}/${DFXMLNAME}" > "${PACKAGE}/${OUTDIR}/${CHECKSUMNAME}"
182182
else
183-
xml sel -T -t -m "/dfxml/fileobject" -v "hashdigest" -o " " -v "filename" -n "${PACKAGE}/${OUTDIR}/${DFXMLNAME}" > "${PACKAGE}/${OUTDIR}/${CHECKSUMNAME}"
183+
xmlstarlet sel -T -t -m "/dfxml/fileobject" -v "hashdigest" -o " " -v "filename" -n "${PACKAGE}/${OUTDIR}/${DFXMLNAME}" > "${PACKAGE}/${OUTDIR}/${CHECKSUMNAME}"
184184
fi
185185
db_source="${PACKAGE}/${OUTDIR}/${CHECKSUMNAME}"
186186
db_fixity=$(cat "${PACKAGE}/${OUTDIR}/${CHECKSUMNAME}")

ingestfile

+38-11
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ _ask_digitization_logs(){
8282
# spreadsheet fields are currently CUNY-specific
8383
_parse_spreadsheet(){
8484
DIGITIZATIONLOG=$(_maketemp)
85-
paste -d"*" <(ssconvert -T Gnumeric_html:xhtml_range "${FILES}" fd://1 | xml fo | xml select --no-doc-namespace -t -m "_:html/_:body/_:table[1]/_:tr[1]/_:td" -v "." -n) <(ssconvert -T Gnumeric_html:xhtml_range "${FILES}" fd://1 | xml fo | xml select --no-doc-namespace -t -m "_:html/_:body/_:table[1]/_:tr[_:td[1]='${MEDIAID}']/_:td" -v "." -n) | sed "s/*/\: /g" | tee "${DIGITIZATIONLOG}"
85+
paste -d"*" <(ssconvert -T Gnumeric_html:xhtml_range "${FILES}" fd://1 | xmlstarlet fo | xmlstarlet select --no-doc-namespace -t -m "_:html/_:body/_:table[1]/_:tr[1]/_:td" -v "." -n) <(ssconvert -T Gnumeric_html:xhtml_range "${FILES}" fd://1 | xmlstarlet fo | xmlstarlet select --no-doc-namespace -t -m "_:html/_:body/_:table[1]/_:tr[_:td[1]='${MEDIAID}']/_:td" -v "." -n) | sed "s/*/\: /g" | tee "${DIGITIZATIONLOG}"
8686
cat "${DIGITIZATIONLOG}" >> "${INGESTLOG}"
8787
OBJECTSOUNDFIELD=$(_readingestlog "object soundfield")
8888
DECKHEADSETTING=$(_readingestlog "deck head setting")
@@ -100,11 +100,10 @@ _parse_spreadsheet(){
100100
}
101101
102102
_get_xmp_info(){
103-
WAV="${INPUT}"
104-
XMP_SIZE=$(mediaconch -mt "${WAV}" | xmlstarlet sel -N "mt=https://mediaarea.net/mediatrace" -t -m "mt:MediaTrace/mt:media/mt:block[@name='Wave']/mt:block[@name='_PMX']" -v "mt:block[@name='Header']/mt:data[@name='Size']" -n)
105-
XMP_OFFSET=$(mediaconch -mt "${WAV}" | xmlstarlet sel -N "mt=https://mediaarea.net/mediatrace" -t -m "mt:MediaTrace/mt:media/mt:block[@name='Wave']/mt:block[@name='_PMX']" -v "mt:data/@offset" -n)
103+
XMP_SIZE=$(mediaconch -mt "${INPUT}" | xmlstarlet sel -N "mt=https://mediaarea.net/mediatrace" -t -m "mt:MediaTrace/mt:media/mt:block[@name='Wave']/mt:block[@name='_PMX']" -v "mt:block[@name='Header']/mt:data[@name='Size']" -n)
104+
XMP_OFFSET=$(mediaconch -mt "${INPUT}" | xmlstarlet sel -N "mt=https://mediaarea.net/mediatrace" -t -m "mt:MediaTrace/mt:media/mt:block[@name='Wave']/mt:block[@name='_PMX']" -v "mt:data/@offset" -n)
106105
XMP_OFFSET=$(echo "${XMP_OFFSET} + 1" | bc)
107-
XMP_DATA=$(tail -c "+${XMP_OFFSET}" "$WAV" | head -c "${XMP_SIZE}" | xml fo)
106+
XMP_DATA=$(tail -c "+${XMP_OFFSET}" "${INPUT}" | head -c "${XMP_SIZE}" | xmlstarlet fo)
108107
GET_INFO=$(echo "${XMP_DATA}" | xmlstarlet sel -N rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" -N xmpDM="http://ns.adobe.com/xmp/1.0/DynamicMedia/" -t -m "//rdf:li[@rdf:parseType='Resource'][xmpDM:trackName='CuePoint Markers']" -o "inSample:" -v "xmpDM:markers/rdf:Seq/rdf:li[@rdf:parseType='Resource']/xmpDM:startTime" -n -o "durationSample:" -v "xmpDM:markers/rdf:Seq/rdf:li[@rdf:parseType='Resource']/xmpDM:duration" -n)
109108
INSAMPLE=$(echo "${XMP_DATA}" | xmlstarlet sel -N rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" -N xmpDM="http://ns.adobe.com/xmp/1.0/DynamicMedia/" -t -m "//rdf:li[@rdf:parseType='Resource'][xmpDM:trackName='CuePoint Markers']" -v "xmpDM:markers/rdf:Seq/rdf:li[@rdf:parseType='Resource']/xmpDM:startTime" -n)
110109
DURATIONSAMPLE=$(echo "${XMP_DATA}" | xmlstarlet sel -N rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" -N xmpDM="http://ns.adobe.com/xmp/1.0/DynamicMedia/" -t -m "//rdf:li[@rdf:parseType='Resource'][xmpDM:trackName='CuePoint Markers']" -v "xmpDM:markers/rdf:Seq/rdf:li[@rdf:parseType='Resource']/xmpDM:duration" -n)
@@ -115,6 +114,30 @@ _get_xmp_info(){
115114
echo "The intime in samples is $INTIME, the outtime in seconds is $OUTTIME, and the duration in seconds is $DURATION."
116115
}
117116
117+
_audioreport(){
118+
ffmpeg -nostdin -i "${INPUT}" -vn -filter_complex "silencedetect,astats,loudnorm=print_format=json,agate=attack=0.01:release=0.01:ratio=9000,aphasemeter=r=0.2:video=0,ametadata=mode=print:key=lavfi.aphasemeter.phase:value=-0.18:function=less" -f null - 2>&1 | tr "\r" "\n" > /tmp/loud
119+
MEASURED_I=$(cat /tmp/loud | grep "input_i" | awk -F\" '{print $4}')
120+
MEASURED_LRA=$(cat /tmp/loud | grep "input_lra" | awk -F\" '{print $4}')
121+
MEASURED_TP=$(cat /tmp/loud | grep "input_tp" | awk -F\" '{print $4}')
122+
MEASURED_THRESH=$(cat /tmp/loud | grep "input_thresh" | awk -F\" '{print $4}')
123+
TARGET_OFFSET=$(cat /tmp/loud | grep "target_offset" | awk -F\" '{print $4}')
124+
BWFMETAEDIT=$(bwfmetaedit "${INPUT}" 2>&1 | awk '{printf "%s+",$0} END {print ""}')
125+
FLATFACTOR=$(cat /tmp/loud | grep "Flat factor: " | tail -n +3 | head -n 1 | cut -d ":" -f 2 | sed 's/ //g')
126+
echo " MEASURED_I = ${MEASURED_I}"
127+
echo " MEASURED_LRA = ${MEASURED_LRA}"
128+
echo " MEASURED_TP = ${MEASURED_TP}"
129+
echo " MEASURED_THRESH = ${MEASURED_THRESH}"
130+
echo " TARGET_OFFSET = ${TARGET_OFFSET}"
131+
echo " BWFMETAEDIT = ${BWFMETAEDIT}"
132+
if [[ "${FLATFACTOR}" != 0.000000 ]] ; then
133+
_report -wt "WARNING - There are ${FLATFACTOR} flat sections of waveform that may indicate clipped audio."
134+
_report -qn "Enter q to quit, any other key to continue: "
135+
read A4
136+
[ "${A4}" == "q" ] && exit 0
137+
_writeingestlog "Flat sections of audio waveform" "${FLATFACTOR}"
138+
fi
139+
}
140+
118141
_blackframetest(){
119142
_black_at_ends "${INPUT}"
120143
if [ "${HEAD_BLACK}" -gt "30" ] ; then
@@ -368,6 +391,7 @@ AUDIODECISION.option =
368391
AUDIODECISION.option = Default audio mapping [first audio track used for stereo output]
369392
AUDIODECISION.option = Only use left of the first audio track [for 21st Century]
370393
AUDIODECISION.option = Only use right of the first audio track
394+
AUDIODECISION.option = Only use the first track
371395
AUDIODECISION.width = 400
372396
373397
# cropping strategy
@@ -501,7 +525,7 @@ fi
501525
if [[ -z "${AUDIODECISION}" ]] ; then
502526
_report -q "Select an audio strategy?"
503527
PS3="Selection: "
504-
select AUDIODECISION in "Default audio mapping [first audio track used for stereo output]" "Only use left of the first audio track [for 21st Century]" "Only use right of the first audio track"
528+
select AUDIODECISION in "Default audio mapping [first audio track used for stereo output]" "Only use left of the first audio track [for 21st Century]" "Only use right of the first audio track" "Only use the first track"
505529
do
506530
break
507531
done
@@ -571,7 +595,9 @@ if [[ "${MODE}" == "preservation" ]] ; then
571595
if [[ "${FORMULA}" == "check interlacement" ]] ; then
572596
_get_interlacement_full "${INPUT}"
573597
fi
574-
elif [[ "${MODE}" != "audio" ]] ; then
598+
elif [[ "${MODE}" == "audio" ]] ; then
599+
_audioreport
600+
else
575601
# presumes default, psa, or local mode
576602
_blackframetest
577603
_phasechecktest
@@ -629,11 +655,12 @@ else
629655
fi
630656
fi
631657
658+
# set makederivopts
632659
unset MAKEDERIVOPTS
633-
[ "${AUDIODECISION}" == "Only use left of the first audio track [for 21st Century]" -o "${AUDIODECISION}" == "left" ] && MAKEDERIVOPTS+=(-l)
634-
[ "${AUDIODECISION}" == "Only use right of the first audio track" ] && MAKEDERIVOPTS+=(-r)
635-
[ "${CROPDECISION}" == "Examine the video and auto-crop out black borders (slower)" ] && MAKEDERIVOPTS+=(-c)
636-
if [ ! -z "${FORMULA}" ] ; then
660+
if [[ "${CROPDECISION}" == "Examine the video and auto-crop out black borders (slower)" ]] ; then
661+
MAKEDERIVOPTS+=(-c)
662+
fi
663+
if [[ ! -z "${FORMULA}" ]] ; then
637664
MAKEDERIVOPTS+=(-F "${FORMULA}")
638665
fi
639666

0 commit comments

Comments
 (0)