Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assigns standard values to matroska video properties #251

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
382 changes: 382 additions & 0 deletions standardguess
Original file line number Diff line number Diff line change
@@ -0,0 +1,382 @@
#!/bin/bash
#checks to see if a video's properties are consistent with a set of standards and if so it assigns expected values to other properties if they are undefined or differ from expectations

SCRIPTDIR=$(dirname $(which "${0}"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

worth quoting the $() layer too, such as SCRIPTDIR="$(dirname $(which "${0}")")

. "${SCRIPTDIR}/mmfunctions" || { echo "Missing '${SCRIPTDIR}/mmfunctions'. Exiting." ; exit 1 ;};

_get_frame_rate(){
FRAMERATE=$(ffprobe -i "${1}" -v error -select_streams v:0 -show_entries stream=avg_frame_rate -of default=noprint_wrappers=1:nokey=0 | grep "^avg_frame_rate=" | cut -d = -f 2)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should add a dependency check on the tools used, such as ffprobe, mkvinfo, and mkvpropedit. The dependencies are listed in an array such as

DEPENDENCIES=(ffmpeg ffprobe)
and then checked with a function from mmfunction such as

mm/fix_rewrap

Line 21 in 437c6c7

_check_dependencies "${DEPENDENCIES[@]}"

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also is -v error useful here, it may just make the output noisy.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you set nokey=1 then you won't need to pipe to grep and cut to parse the value.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that -v error tells ffprobe to report errors only. Without it prints out all the version info for ffmpeg, ffprobe, etc...

}
_get_format(){
FORMAT=$(ffprobe -i "${1}" -v error -select_streams v:0 -show_format -of default=noprint_wrappers=1:nokey=0 | grep "^format_name=" | cut -d = -f 2)
}
_MKV_Prop_Check(){

ELEMENT="$2"
EXPECTATION="$3"
MKVINFO_PROP=$(mkvinfo -t "${1}")
SELECTED_ELEMENT=$(echo "${MKVINFO_PROP}" | grep -c "+ ${ELEMENT}:")
SELECTED_ELEMENT_VALUE=$(echo "${MKVINFO_PROP}" | grep -i "+ ${ELEMENT}: " | cut -d: -f 2 | sed 's/ //g' | sed 's/(aspectratio)//g')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is aspectratio referenced like this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aspect ratio shows up in the MKVinfo report next to the assigned value. I used sed to take it out and just get the value but now I'm thinking that if there was any other value assigned to the display unit it might the definition too, so i have changed that line to:

SELECTED_ELEMENT_VALUE=$(echo "${MKVINFO_PROP}" | grep -i "+ ${ELEMENT}: " | cut -d: -f 2 | cut -d" " -f 2) 


if [[ "${SELECTED_ELEMENT}" != "0" ]]; then
if [[ "${SELECTED_ELEMENT_VALUE}" -eq "${EXPECTATION}" ]]; then
echo "${ELEMENT} -eq expectation ${EXPECTATION}"
elif [[ "${SELECTED_ELEMENT_VALUE}" == "${EXPECTATION}" ]]; then
echo "${ELEMENT} == expectation ${EXPECTATION}"
else
echo "${ELEMENT} is not ${EXPECTATION} but it has the specified value of ${SELECTED_ELEMENT_VALUE}"
fi
else
echo "${ELEMENT} is not present"
fi
}
_MKV_Interlaced(){
MKVINTERLACED=$(_MKV_Prop_Check "${1}" "Interlaced" "1")
}
_MKV_WIDTH(){
MKVWIDTH=$(_MKV_Prop_Check "${1}" "Display width" "4")
}
_MKV_HEIGHT(){
MKVHEIGHT=$(_MKV_Prop_Check "${1}" "Display height" "3")
}
_MKV_UNIT(){
MKVUNIT=$(_MKV_Prop_Check "${1}" "Display unit" "3")
}
_MKV_RANGE(){
MKVRANGE=$(_MKV_Prop_Check "${1}" "Colour range" "1")
}
_MKV_TRANSFER(){
MKVTRANSFER=$(_MKV_Prop_Check "${1}" "Colour transfer" "1")
}
_MKV_PRIMARIES(){
MKVPRIMARIES=$(_MKV_Prop_Check "${1}" "Colour primaries" "6")
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these above functions needed, from _MKV_Interlaced through _MKV_PRIMARIES? It seems that when they are used below the _MKV_Prop_Check version is also used, so many tests happen twice.

_get_video_track(){
VIDEOTRACK=$(mkvmerge -i "${1}" | grep -i "video" | cut -d " " -f 3 | sed 's/://g')

TRACKNUMBER=$(expr "${VIDEOTRACK}" + 1)
}
_APPLY_STANDARDS(){
PROPNAME="${2}"
ASSIGNVALUE="${3}"
mkvpropedit "${1}" -e track:v"${TRACKNUMBER}" -s "${PROPNAME}"="${ASSIGNVALUE}"
PROPMOD="$?"

if [[ "${PROPMOD}" = "0" ]]; then
echo "The ${PROPNAME} has been assigned a value of ${ASSIGNVALUE}"
else
echo -e "\033[1;5;31;40mA problem has occured\033[0m"
mkvpropedit "${PROPMOD}"
fi
}
_usage(){
echo "This application checks if a matroska video is consistent with a set of standards properties and if so, it will assign expected values to other properties that are either undefined or differ from expectations. The properties that will be changed to their expected values are as follows:"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC this would only apply these properties if the input is NTSC. If so then the usage should clarify this.

echo
echo "Interlaced = 1"
echo "Display width = 4"
echo "Display height = 3"
echo "Display unit = 3"
echo "Colour range = 1"
echo "Colour transfer = 1"
echo "Colour primaries = 6"
echo
echo "By default, when the application finds a property with an assigned value that differs from the expected value, it will ask the user whether the original value should be changed to the expected value."
echo
echo "-f to apply the expected value to all properties regardless of existing values without requiring user input"
echo "-r to retain existing property values that differ from expected values without requiring user input"
echo
echo "Only one option can be exercised at a time and whichever option in entered first will be applied to all"
echo
echo "-h to display this help"
echo
exit
}

user_input="${@}"
OPTIND=1
while getopts ":frh" OPT ; do
case "${OPT}" in
f) echo ; echo -e "\033[1;35mAll property values that differ from their expected values will be reassigned to their expected values\033[0m" ; FORCE="1" ;;
r) echo ; echo -e "\033[1;34mAll existing property values will be retained. All unassigned values will be assigned their expected values\033[0m" ; RETAIN="1" ;;
h) _usage ;;
*) echo -e "\033[1;5;37;40mbad option -${OPTARG}\033[0m" ; _usage ;;
esac
done
shift $(( ${OPTIND} - 1 ))

while [[ "${@}" != "" ]] ; do
INPUT="${1}"
echo
echo -e "\033[1;36m${INPUT}\033[0m"
shift

if [[ "${INPUT}" != *.mkv ]]; then
echo -e "\033[1;5;37;40mERROR:\033[0m Input files must be Matroska video, \033[31m${INPUT}\033[0m does not meet this requirement and will not be processed"
echo
continue
fi

_get_width "${INPUT}"
_get_height "${INPUT}"
_get_frame_rate "${INPUT}"
_get_format "${INPUT}"

if [[ "${WIDTH}" = "720" && "${HEIGHT}" = "486" || "${HEIGHT}" = "480" ]] && [[ "${FRAMERATE}" = "30000/1001" || "${FRAMERATE}" = "29970/1001" ]] && [[ "${FORMAT}" = "matroska,webm" ]]; then
echo "Standard video specifications detected"
echo "Checking MKV properties"
echo
else
echo -e "\033[1;5;37;40mERROR:\033[0m Video specifications do not conform to the standard configuration required, \033[31m${INPUT}\033[0m will not be processed"
echo
continue
fi


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lots of multiple consecutive line breaks in this doc can be removed.

#ELEMENT is property name as it appears in mkvINFO report
#EXPECTATION is expected value of property
#MKVINFO_PROP generates mkvINFO report
#SELECTED_ELEMENT checks to see if property is present in the mkvINFO report
#SELECTED_ELEMENT_VALUE checks the value of the value of the property
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keep indentation consistent



_MKV_Prop_Check "${INPUT}" "Interlaced" "1"
_MKV_Prop_Check "${INPUT}" "Display width" "4"
_MKV_Prop_Check "${INPUT}" "Display height" "3"
_MKV_Prop_Check "${INPUT}" "Display unit" "3"
_MKV_Prop_Check "${INPUT}" "Colour range" "1"
_MKV_Prop_Check "${INPUT}" "Colour transfer" "1"
_MKV_Prop_Check "${INPUT}" "Colour primaries" "6"


_get_video_track "${INPUT}"
echo
echo "The video track has an mkvmerge track ID of ${VIDEOTRACK}"
echo "The track number ${TRACKNUMBER} is the video track"
echo "Expected values are now going to be applied to the following properties:"


#PROPNAME is property name as it appears in mkvPROPEDIT
#ASSIGNVALUE is the desired value of that property
#using mkvPROPEDIT set the property to the desired value
#PROPMOD is the mkvPROPEDIT exit code 0, 1, 2



echo
echo "Interlaced"
_MKV_Prop_Check "${INPUT}" "Interlaced" "1"
_MKV_Interlaced "${INPUT}"

if [[ $(echo "${MKVINTERLACED}") == "${ELEMENT} is not present" ]]; then
echo "Applying standard value to ${ELEMENT} of ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "interlaced" "1"
elif [[ "${RETAIN}" == "1" ]]; then
echo "${ELEMENT} will retain the original value of ${SELECTED_ELEMENT_VALUE}"
elif [[ "${MKVINTERLACED}" == "${ELEMENT} is not ${EXPECTATION} but it has the specified value of ${SELECTED_ELEMENT_VALUE}" ]] && [[ "${FORCE}" == "1" ]]; then
echo "${ELEMENT} is being reset from ${SELECTED_ELEMENT_VALUE} to ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "interlaced" "1"
elif [[ "${MKVINTERLACED}" == "${ELEMENT} is not ${EXPECTATION} but it has the specified value of ${SELECTED_ELEMENT_VALUE}" ]] && [[ "${FORCE}" != "1" ]]; then
read -e -p "Are you sure you would like to reset ${ELEMENT} to ${EXPECTATION}? [y/n] " choice
echo
if [[ "${choice}" == [Yy] ]]; then
echo "${ELEMENT} is being reset from ${SELECTED_ELEMENT_VALUE} to ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "interlaced" "1"
else
echo "${ELEMENT} will retain the original value of ${SELECTED_ELEMENT_VALUE}"
fi
else
echo "${ELEMENT} already set to expected value of ${EXPECTATION}"
fi






echo
echo "Width"
_MKV_Prop_Check "${INPUT}" "Display width" "4"
_MKV_WIDTH "${INPUT}"

if [[ "${MKVWIDTH}" == "${ELEMENT} is not present" ]]; then
echo "Applying standard value to ${ELEMENT} of ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "display-width" "4"
elif [[ "${RETAIN}" == "1" ]]; then
echo "${ELEMENT} will retain the original value of ${SELECTED_ELEMENT_VALUE}"
elif [[ "${MKVWIDTH}" == "${ELEMENT} is not ${EXPECTATION} but it has the specified value of ${SELECTED_ELEMENT_VALUE}" ]] && [[ "${FORCE}" == "1" ]]; then
echo "${ELEMENT} is being reset from ${SELECTED_ELEMENT_VALUE} to ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "display-width" "4"
elif [[ "${MKVWIDTH}" == "${ELEMENT} is not ${EXPECTATION} but it has the specified value of ${SELECTED_ELEMENT_VALUE}" ]] && [[ "${FORCE}" != "1" ]]; then
read -e -p "Are you sure you would like to reset ${ELEMENT} to ${EXPECTATION}? [y/n] " choice
echo
if [[ "${choice}" == [Yy] ]]; then
echo "${ELEMENT} is being reset from ${SELECTED_ELEMENT_VALUE} to ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "display-width" "4"
else
echo "${ELEMENT} will retain the original value of ${SELECTED_ELEMENT_VALUE}"
fi
else
echo "${ELEMENT} already set to expected value of ${EXPECTATION}"
fi





echo
echo "Height"
_MKV_Prop_Check "${INPUT}" "Display height" "3"
_MKV_HEIGHT "${INPUT}"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These prior two lines seem to do the same thing.


if [[ "${MKVHEIGHT}" == "${ELEMENT} is not present" ]]; then
echo "Applying standard value to ${ELEMENT} of ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "display-height" "3"
elif [[ "${RETAIN}" == "1" ]]; then
echo "${ELEMENT} will retain the original value of ${SELECTED_ELEMENT_VALUE}"
elif [[ "${MKVHEIGHT}" == "${ELEMENT} is not ${EXPECTATION} but it has the specified value of ${SELECTED_ELEMENT_VALUE}" ]] && [[ "${FORCE}" == "1" ]]; then
echo "${ELEMENT} is being reset from ${SELECTED_ELEMENT_VALUE} to ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "display-height" "3"
elif [[ "${MKVHEIGHT}" == "${ELEMENT} is not ${EXPECTATION} but it has the specified value of ${SELECTED_ELEMENT_VALUE}" ]] && [[ "${FORCE}" != "1" ]]; then
read -e -p "Are you sure you would like to reset ${ELEMENT} to ${EXPECTATION}? [y/n] " choice
echo
if [[ "${choice}" == [Yy] ]]; then
echo "${ELEMENT} is being reset from ${SELECTED_ELEMENT_VALUE} to ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "display-height" "3"
else
echo "${ELEMENT} will retain the original value of ${SELECTED_ELEMENT_VALUE}"
fi
else
echo "${ELEMENT} already set to expected value of ${EXPECTATION}"
fi
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The above section seems to be re-used within the context of several different properties. It make reduce line count and make this easier to maintain if this section was adjusted to be a generic function which could be re-used within each context.







echo
echo "Display Unit"
_MKV_Prop_Check "${INPUT}" "Display unit" "3"
_MKV_UNIT "${INPUT}"

if [[ "${MKVUNIT}" == "${ELEMENT} is not present" ]]; then
echo "Applying standard value to ${ELEMENT} of ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "display-unit" "3"
elif [[ "${RETAIN}" == "1" ]]; then
echo "${ELEMENT} will retain the original value of ${SELECTED_ELEMENT_VALUE}"
elif [[ "${MKVUNIT}" == "${ELEMENT} is not ${EXPECTATION} but it has the specified value of ${SELECTED_ELEMENT_VALUE}" ]] && [[ "${FORCE}" == "1" ]]; then
echo "${ELEMENT} is being reset from ${SELECTED_ELEMENT_VALUE} to ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "display-unit" "3"
elif [[ "${MKVUNIT}" == "${ELEMENT} is not ${EXPECTATION} but it has the specified value of ${SELECTED_ELEMENT_VALUE}" ]] && [[ "${FORCE}" != "1" ]]; then
read -e -p "Are you sure you would like to reset ${ELEMENT} to ${EXPECTATION}? [y/n] " choice
echo
if [[ "${choice}" == [Yy] ]]; then
echo "${ELEMENT} is being reset from ${SELECTED_ELEMENT_VALUE} to ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "display-unit" "3"
else
echo "${ELEMENT} will retain the original value of ${SELECTED_ELEMENT_VALUE}"
fi
else
echo "${ELEMENT} already set to expected value of ${EXPECTATION}"
fi






echo
echo "Colour Range"
_MKV_Prop_Check "${INPUT}" "Colour range" "1"
_MKV_RANGE "${INPUT}"

if [[ "${MKVRANGE}" == "${ELEMENT} is not present" ]]; then
echo "Applying standard value to ${ELEMENT} of ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "colour-range" "1"
elif [[ "${RETAIN}" == "1" ]]; then
echo "${ELEMENT} will retain the original value of ${SELECTED_ELEMENT_VALUE}"
elif [[ "${MKVRANGE}" == "${ELEMENT} is not ${EXPECTATION} but it has the specified value of ${SELECTED_ELEMENT_VALUE}" ]] && [[ "${FORCE}" == "1" ]]; then
echo "${ELEMENT} is being reset from ${SELECTED_ELEMENT_VALUE} to ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "colour-range" "1"
elif [[ "${MKVRANGE}" == "${ELEMENT} is not ${EXPECTATION} but it has the specified value of ${SELECTED_ELEMENT_VALUE}" ]] && [[ "${FORCE}" != "1" ]]; then
read -e -p "Are you sure you would like to reset ${ELEMENT} to ${EXPECTATION}? [y/n] " choice
echo
if [[ "${choice}" == [Yy] ]]; then
echo "${ELEMENT} is being reset from ${SELECTED_ELEMENT_VALUE} to ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "colour-range" "1"
else
echo "${ELEMENT} will retain the original value of ${SELECTED_ELEMENT_VALUE}"
fi
else
echo "${ELEMENT} already set to expected value of ${EXPECTATION}"
fi






echo
echo "Colour Transfer"
_MKV_Prop_Check "${INPUT}" "Colour transfer" "1"
_MKV_TRANSFER "${INPUT}"

if [[ "${MKVTRANSFER}" == "${ELEMENT} is not present" ]]; then
echo "Applying standard value to ${ELEMENT} of ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "colour-transfer-characteristics" "1"
elif [[ "${RETAIN}" == "1" ]]; then
echo "${ELEMENT} will retain the original value of ${SELECTED_ELEMENT_VALUE}"
elif [[ "${MKVTRANSFER}" == "${ELEMENT} is not ${EXPECTATION} but it has the specified value of ${SELECTED_ELEMENT_VALUE}" ]] && [[ "${FORCE}" == "1" ]]; then
echo "${ELEMENT} is being reset from ${SELECTED_ELEMENT_VALUE} to ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "colour-transfer-characteristics" "1"
elif [[ "${MKVTRANSFER}" == "${ELEMENT} is not ${EXPECTATION} but it has the specified value of ${SELECTED_ELEMENT_VALUE}" ]] && [[ "${FORCE}" != "1" ]]; then
read -e -p "Are you sure you would like to reset ${ELEMENT} to ${EXPECTATION}? [y/n] " choice
echo
if [[ "${choice}" == [Yy] ]]; then
echo "${ELEMENT} is being reset from ${SELECTED_ELEMENT_VALUE} to ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "colour-transfer-characteristics" "1"
else
echo "${ELEMENT} will retain the original value of ${SELECTED_ELEMENT_VALUE}"
fi
else
echo "${ELEMENT} already set to expected value of ${EXPECTATION}"
fi






echo
echo "Colour Primaries"
_MKV_Prop_Check "${INPUT}" "Colour primaries" "6"
_MKV_PRIMARIES "${INPUT}"

if [[ "${MKVPRIMARIES}" == "${ELEMENT} is not present" ]]; then
echo "Applying standard value to ${ELEMENT} of ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "colour-primaries" "6"
elif [[ "${RETAIN}" == "1" ]]; then
echo "${ELEMENT} will retain the original value of ${SELECTED_ELEMENT_VALUE}"
elif [[ "${MKVPRIMARIES}" == "${ELEMENT} is not ${EXPECTATION} but it has the specified value of ${SELECTED_ELEMENT_VALUE}" ]] && [[ "${FORCE}" == "1" ]]; then
echo "${ELEMENT} is being reset from ${SELECTED_ELEMENT_VALUE} to ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "colour-primaries" "6"
elif [[ "${MKVPRIMARIES}" == "${ELEMENT} is not ${EXPECTATION} but it has the specified value of ${SELECTED_ELEMENT_VALUE}" ]] && [[ "${FORCE}" != "1" ]]; then
read -e -p "Are you sure you would like to reset ${ELEMENT} to ${EXPECTATION}? [y/n] " choice
echo
if [[ "${choice}" == [Yy] ]]; then
echo "${ELEMENT} is being reset from ${SELECTED_ELEMENT_VALUE} to ${EXPECTATION}"
_APPLY_STANDARDS "${INPUT}" "colour-primaries" "6"
else
echo "${ELEMENT} will retain the original value of ${SELECTED_ELEMENT_VALUE}"
fi
else
echo "${ELEMENT} already set to expected value of ${EXPECTATION}"
fi
done
exit
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An exit as a last line is not needed.