Vous n'êtes pas identifié(e).
L'icône rouge permet de télécharger chaque page du wiki visitée au format PDF et la grise au format ODT →
Ceci est une ancienne révision du document !
Slymedia est un script (amateur) qui permet de convertir les fichiers vidéo et audio.
Paquets pour le fonctionne du script:
apt update apt install aptitude aptitude install ffmpeg yad flac vorbis-tools eyed3 kid3-cli apt upgrade
#! /bin/bash # Paquets à installer: ffmpeg yad flac vorbis-tools eyed3 kid3-cli # Version: 20180817 #=========================================================================================================== function YADMAIN() { yadMain=$(yad --form \ --geometry="640x720" \ --borders="20" \ --title "SlyMedia" \ --item-separator="!" \ --columns=1 \ --scroll \ --field=" ":LBL " " \ --field="<b>Profil</b>":CB "${profile}!Audio FLAC!Audio vorbis!Audio aac!Audio mp3!Vidéo mkv - x264 - vorbis!Vidéo mkv - x264 - aac!Vidéo mkv - x264 - mp3!Vidéo mkv - x265 - vorbis!Vidéo mkv - x265 - aac!Vidéo mkv - x265 - mp3" \ --field=" ":LBL " " \ --field="<b>Qualité</b>":CB "${quality}!Excellente!Elevée!Moyenne!Minimum!Faible" \ --field=" ":LBL " " \ --field="<b>Dossier destination</b>":DIR "${dirOut}" \ --field=" ":LBL " " \ --field="":LBL "" \ --field="<b>Source</b>":LBL " " \ --field=" ":LBL " " \ --button="Quitter!gtk-quit!:1" \ --button="Options par défaut!gtk-refresh!:3" \ --button="Préférences!gtk-preferences!:2" \ --button="Source!gtk-file!:4" \ --button="Lancer conversion!gtk-convert!:0" \ "${TabYadStream[@]}") # Status de sortie Yad status="$?" # Récupération variables profile=$(awk -F [\|] '{print $2}' <<< "${yadMain}") quality=$(awk -F [\|] '{print $4}' <<< "${yadMain}") dirOut=$(awk -F [\|] '{print $6}' <<< "${yadMain}") } #=========================================================================================================== function YADPREFERENCE() { # Sélection du ou des fichiers source yadPreference=$(yad --form \ --title "SlyMedia" \ --geometry="640x720" \ --borders="20" \ --field="<b>Préférences vidéo</b>":LBL " " \ --field="Définition de la vidéo":CB "${definition}!Identique à la source!3840x2160 (UHD 16:9)!1920x1080 (FULL-HD 16:9)!1280x720 (HD 16:9)!1024x576 (16:9)!768x432 (16:9)!512x288 (16:9)!256x144 (16:9)!720x576 (SD PAL)!720x480 (SD NTSC)!640x480 (4:3)!320x240 (4:3)!1024x768 (4:3)!1280x960 (4:3)!1280x800 (16:10)!1440x900 (16:10)!1680x1050 (16:10)!1920x1200 (16:10)!2560x1600 (16:10)" \ --field=" ":LBL " " \ --field=" ":LBL " " \ --field=" ":LBL " " \ --field="<b>Préférences audio</b>":LBL " " \ --field="Langue audio préférée":CB "${langAudio}!Toutes les langues!Aucune!Français!Allemand!Anglais!Arabe!Espagnol!Espéranto!Italien!Japonais!Latin!Luxembourgeois!Néerlandais!Portugais!Romanche!Russe" \ --field=" ":LBL " " \ --field="Débit binaire":CB "${typeRate}!VBR!CBR" \ --field=" ":LBL " " \ --field=" ":LBL " " \ --field=" ":LBL " " \ --field="<b>Préférences sous-titre</b>":LBL " " \ --field="Langue sous-titre préférée":CB "${langSub}!Toutes les langues!Aucune!Français!Allemand!Anglais!Arabe!Espagnol!Espéranto!Italien!Japonais!Latin!Luxembourgeois!Néerlandais!Portugais!Romanche!Russe" \ --field=" ":LBL " " \ --field=" ":LBL " " \ --field=" ":LBL " " \ --field="<b>Options</b>":LBL " " \ --field="Supprimer tous les tags et images cover":CHK "${metadata}" \ --field="Ne pas encoder si même codec que l'original":CHK "${nocopy}" \ --field="Dossier source":DIR "${dirIn}" \ --button="gtk-quit:1" \ --button="gtk-cancel:2" \ --button="gtk-ok:0") # Status de sortie Yad status="$?" # Récupération variables definition=$(awk -F [\|] '{print $2}' <<< "${yadPreference}") langAudio=$(awk -F [\|] '{print $7}' <<< "${yadPreference}") typeRate=$(awk -F [\|] '{print $9}' <<< "${yadPreference}") langSub=$(awk -F [\|] '{print $14}' <<< "${yadPreference}") metadata=$(awk -F [\|] '{print $19}' <<< "${yadPreference}") nocopy=$(awk -F [\|] '{print $20}' <<< "${yadPreference}") dirIn=$(awk -F [\|] '{print $21}' <<< "${yadPreference}") } #=========================================================================================================== function YADSOURCE() { IFS=$"|" yadSource=$(yad --list \ --radiolist \ --title="Slymedia" \ --text="Choississez une source" \ --print-all \ --geometry="320x300" \ --borders="20" \ --center \ --button="gtk-quit:1" \ --button="gtk-cancel:2" \ --button="gtk-ok:0" \ --column="" \ --column="Type de source" \ "FALSE" "Fichier avec analyse" \ "TRUE" "Fichier" \ "FALSE" "DVD" \ "FALSE" "CD" \ "FALSE" "DDL") # Status de sortie Yad status="$?" # Récupération variables source=$(awk -F [\|] '/TRUE/ {print $2}' <<< "${yadSource}") } #=========================================================================================================== function YADFILE() { # Sélection du ou des fichiers source fileIn=$(yad --file \ --multiple \ --title "SlyMedia" \ --geometry="640x720" \ --borders="20" \ --separator="\n" \ --center \ --file-filter="Fichier media | *mkv *.ogg *.mp4 *.avi *.vob *.flac *.mp3 *.m4a" \ --file-filter "Tous | *" \ --filename="${dirIn}" \ --button="gtk-quit:1" \ --button="gtk-cancel:2" \ --button="gtk-ok:0") # Status de sortie Yad status="$?" } #=========================================================================================================== function YADPROGRESS() { yad --progress \ --title "SlyEditImage ${version}" \ --geometry="550x300" \ --borders="25" \ --auto-close \ --auto-kill \ --button="gtk-media-stop:1" yadStatus="$?" } #=========================================================================================================== function CONFIGURATION() { # Création du dossier .slymedia dirSylmedia="/home/$USER/.slymedia" [[ ! -d "${dirSylmedia}" ]] && mkdir "${dirSylmedia}" # Suppression des anciens dossiers temporaires rm -rf "${dirSylmedia}"/tmp* # Création du dossier temporaire dossierTmp="$(mktemp -d "${dirSylmedia}/tmp-XXXXXXXXXXX")" # Création du fichier de configurations fileConfig="${dirSylmedia}/config.txt" [[ ! -f "${fileConfig}" ]] && CONFIGDEFAUT } #=========================================================================================================== function CONFIGDEFAUT() { # Options par défaut echo -e "profile=\"Vidéo mkv - x264 - vorbis\"\nquality=\"Elevée\"\ndirOut=\"${HOME}\"\ndefinition=\"Identique à la source\"\nlangAudio=\"Toutes les langues\"\ntypeRate=\"VBR\"\nlangSub=\"Toutes les langues\"\nmetadata=\"FALSE\"\nnocopy=\"FALSE\"\ndirIn=\"${HOME}/\"" > "${fileConfig}" } #=========================================================================================================== function SAVE() { # Sauvegarde variables dans fichier de configuaration utilisateur echo -e "profile=\"${profile}\"\nquality=\"${quality}\"\ndirOut=\"${dirOut}\"\ndefinition=\"${definition}\"\nlangAudio=\"${langAudio}\"\ntypeRate=\"${typeRate}\"\nlangSub=\"${langSub}\"\nmetadata=\"${metadata}\"\nnocopy=\"${nocopy}\"\ndirIn=\"${dirIn}\"" > "${fileConfig}" echo "profile: ${profile}" echo "quality: ${quality}" echo "dirOut: ${dirOut}" echo "definition: ${definition}" echo "langAudio: ${langAudio}" echo "typeRate: ${typeRate}" echo "langSub: ${langSub}" echo "metadata: ${metadata}" echo "nocopy: ${nocopy}" echo "dirIn: ${dirIn}" echo "==============================================" } #=========================================================================================================== function LANGUE() { if [[ "${lang}" == "fre" ]] || [[ "${lang}" == "fra" ]] || [[ "${lang}" == "fr" ]]; then language="Français" languageISO="fre" elif [[ "${lang}" == "gre" ]] || [[ "${lang}" == "deu" ]] || [[ "${lang}" == "de" ]]; then language="Allemand" languageISO="deu" elif [[ "${lang}" == "eng" ]] || [[ "${lang}" == "en" ]]; then language="Anglais" languageISO="eng" elif [[ "${lang}" == "ara" ]] || [[ "${lang}" == "ar" ]]; then language="Arabe" languageISO="ara" elif [[ "${lang}" == "bre" ]] || [[ "${lang}" == "br" ]]; then language="Breton" languageISO="bre" elif [[ "${lang}" == "cat" ]] || [[ "${lang}" == "ca" ]]; then language="Catalan" languageISO="cat" elif [[ "${lang}" == "chi" ]] || [[ "${lang}" == "zho" ]] || [[ "${lang}" == "zh" ]]; then language="Chinois" languageISO="chi" elif [[ "${lang}" == "kor" ]] || [[ "${lang}" == "ko" ]]; then language="Coréen" languageISO="kor" elif [[ "${lang}" == "cos" ]] || [[ "${lang}" == "co" ]]; then language="Corse" languageISO="cos" elif [[ "${lang}" == "hat" ]] || [[ "${lang}" == "ht" ]]; then language="Créole_haïtien" languageISO="hat" elif [[ "${lang}" == "hat" ]] || [[ "${lang}" == "ht" ]]; then language="Créole_haïtien" languageISO="hat" elif [[ "${lang}" == "rcf" ]] || [[ "${lang}" == "rc" ]]; then language="Créole_Réunionnais" languageISO="rcf" elif [[ "${lang}" == "gla" ]] || [[ "${lang}" == "gd" ]]; then language="Écossais" languageISO="gla" elif [[ "${lang}" == "spa" ]] || [[ "${lang}" == "es" ]]; then language="Espagnol" languageISO="spa" elif [[ "${lang}" == "epo" ]] || [[ "${lang}" == "eo" ]]; then language="Espéranto" languageISO="epo" elif [[ "${lang}" == "fin" ]] || [[ "${lang}" == "fi" ]]; then language="Finnois" languageISO="fin" elif [[ "${lang}" == "glg" ]] || [[ "${lang}" == "gl" ]]; then language="Galicien" languageISO="glg" elif [[ "${lang}" == "wel" ]] || [[ "${lang}" == "cym" ]] || [[ "${lang}" == "cy" ]]; then language="Gallois" languageISO="wel" elif [[ "${lang}" == "gre" ]] || [[ "${lang}" == "ell" ]] || [[ "${lang}" == "el" ]]; then language="Grec" languageISO="gre" elif [[ "${lang}" == "heb" ]] || [[ "${lang}" == "he" ]]; then language="Hébreu" languageISO="heb" elif [[ "${lang}" == "hin" ]] || [[ "${lang}" == "hi" ]]; then language="Hindi" languageISO="hin" elif [[ "${lang}" == "hun" ]] || [[ "${lang}" == "hu" ]]; then language="Hongrois" languageISO="hun" elif [[ "${lang}" == "gle" ]] || [[ "${lang}" == "ga" ]]; then language="Irlandais" languageISO="gle" elif [[ "${lang}" == "ice" ]] || [[ "${lang}" == "isl" ]] || [[ "${lang}" == "is" ]]; then language="Islandais" languageISO="ice" elif [[ "${lang}" == "ita" ]] || [[ "${lang}" == "it" ]]; then language="Italien" languageISO="ita" elif [[ "${lang}" == "jpn" ]] || [[ "${lang}" == "jp" ]]; then language="Japonais" languageISO="jpn" elif [[ "${lang}" == "lat" ]] || [[ "${lang}" == "la" ]]; then language="Latin" languageISO="lat" elif [[ "${lang}" == "ltz" ]] || [[ "${lang}" == "la" ]]; then language="Luxembourgeois" languageISO="ltz" elif [[ "${lang}" == "dut" ]] || [[ "${lang}" == "nld" ]] || [[ "${lang}" == "lb" ]]; then language="Néerlandais" languageISO="dut" elif [[ "${lang}" == "nor" ]] || [[ "${lang}" == "no" ]]; then language="Norvégien" languageISO="nor" elif [[ "${lang}" == "por" ]] || [[ "${lang}" == "pt" ]]; then language="Portugais" languageISO="por" elif [[ "${lang}" == "roh" ]] || [[ "${lang}" == "rm" ]]; then language="Romanche" languageISO="roh" elif [[ "${lang}" == "rus" ]] || [[ "${lang}" == "ru" ]]; then language="Russe" languageISO="rus" elif [[ "${lang}" == "swe" ]] || [[ "${lang}" == "sv" ]]; then language="Suédois" languageISO="swe" else language="Inconnu" languageISO="und" fi } #=========================================================================================================== function STREAM_SIMPLE() { [[ -f "${dossierTmp}/stream.txt" ]] && rm "${dossierTmp}/stream.txt" TabYadStream=() IFS=$'\n' # Initialisation nbr="0" pourcent="0" timeGo="$(date +%s)" # Nombre de fichier nbrFichier=$(awk '/./ {print}' <<< "${fileIn}" | wc -l) # Calcul le pourcent par fichier pourcentFichier=$(echo "scale=15; 100/${nbrFichier}" | bc) for i in ${fileIn}; do # Titre et durée #streamFormat=$(ffprobe -i "${i}" -hide_banner -v quiet -show_entries format=bit_rate -of csv=s="|") #rateTotal=$(ffmpeg -y -i "${i}" 2>&1 | awk '/Duration:/ {printf "%s\n" ,$(NF-1)}') # Mise en mémoire dans tableau TabYadStream TabYadStream=(${TabYadStream[@]} --field="<b>TITRE:</b> $(basename "${i}")":LBL " ") # Nom du fichier fileNameExt=$(basename "${i}") fileName="${fileNameExt%.*}" # Envoi données vers YADPROGRESS pourcent=$(echo "scale=15; (${pourcent}+${pourcentFichier})" | bc) ((nbr+=1)) # Calcul temps restant timeT="$(date +%s)" timeRemainingS=$(echo "scale=15; ((${timeT}-${timeGo})*${nbrFichier}/${nbr})-(${timeT}-${timeGo})" | bc | awk -F"." '{print $1}') timeRemainingHMS=$(date +%T -d "0000-01-01 ${timeRemainingS} seconds") # Envoi données à YADPROGRESS echo "${pourcent}" echo -e "\n#Chargement ${nbr} fichiers sur ${nbrFichier} - Temps restant environ: ${timeRemainingHMS}" done for i in "${TabYadStream[@]}"; do echo "$i" >>"${dossierTmp}/yadStream.txt" done } #=========================================================================================================== function STREAM() { [[ -f "${dossierTmp}/stream.txt" ]] && rm "${dossierTmp}/stream.txt" touch "${dossierTmp}/yadStream.txt" TabYadStream=() # Initialisation nbr="0" pourcent="0" timeGo="$(date +%s)" # Nombre de fichier nbrFichier=$(awk '/./ {print}' <<< "${fileIn}" | wc -l) # Calcul le pourcent par fichier pourcentFichier=$(echo "scale=15; 100/${nbrFichier}" | bc) IFS=$'\n' for iFileIn in ${fileIn}; do STREAMTITLE STREAMVIDEO STREAMAUDIO STREAMSUBTITLE TabYadStream+=( --field=" ":LBL " ") # Nom du fichier fileNameExt=$(basename "${iFileIn}") fileName="${fileNameExt%.*}" # Envoi données vers YADPROGRESS pourcent=$(echo "scale=15; (${pourcent}+${pourcentFichier})" | bc) ((nbr+=1)) # Calcul temps restant timeT="$(date +%s)" timeRemainingS=$(echo "scale=15; ((${timeT}-${timeGo})*${nbrFichier}/${nbr})-(${timeT}-${timeGo})" | bc | awk -F"." '{print $1}') timeRemainingHMS=$(date +%T -d "0000-01-01 ${timeRemainingS} seconds") # Envoi données à YADPROGRESS echo "${pourcent}" echo -e "\n#Analyse ${nbr} fichiers sur ${nbrFichier} - Temps restant environ: ${timeRemainingHMS}" done for i in "${TabYadStream[@]}"; do echo "$i" >>"${dossierTmp}/yadStream.txt" done } #=========================================================================================================== function STREAMTITLE() { # Titre et durée streamFormat=$(ffprobe -i "${iFileIn}" -hide_banner -v quiet -show_entries format=duration,bit_rate -of csv=s="|") durationS=$(awk -F [\|] '{print $2}' <<< "${streamFormat}") durationHMS=$(date +%T -d "0000-01-01 ${durationS} seconds") rateTotal=$(awk -F [\|] '{printf "%d kb/s" ,($3/1000)}' <<< "${streamFormat}") # Mise en mémoire dans tableau TabYadStream TabYadStream+=( --field="<b>TITRE: $(basename "${iFileIn}") - ${durationHMS} - ${rateTotal}</b>":LBL " ") } #=========================================================================================================== function STREAMVIDEO() { while read line; do index=$(awk -F [\|] '{print $2}' <<< "${line}") codec=$(awk -F [\|] '{print $3}' <<< "${line}") width=$(awk -F [\|] '{print $4}' <<< "${line}") height=$(awk -F [\|] '{print $5}' <<< "${line}") fps1=$(awk -F [\|] '{print $6}' <<< "${line}" | awk -F [\/] '{print $1}') fps2=$(awk -F [\|] '{print $6}' <<< "${line}" | awk -F [\/] '{print $2}') # Vérifiction si fps1 et fps2 sont des valeurs numériques if [[ "${fps1}" = +([0-9]) ]] && [[ "${fps2}" = +([0-9]) ]]; then fps=$(echo "${fps1} / ${fps2}" | bc -l | awk '{printf "%.3f" ,$1}') elif [[ "${fps1}" = +([0-9]) ]] && [[ "${fps2}" != +([0-9]) ]]; then fps=$(awk '{printf "%d" ,$1}' <<< "${fps1}") else fps="N/A" fi # Type d'image (Front, back, other) if [[ "${codec}" == "mjpeg" ]] || [[ "${codec}" == "png" ]]; then # Recherche map depuis numéro id id=$(awk -F [\:] '{print $2}' <<< "0:${index}") typeImage=$(ffprobe -i "${i}" -hide_banner -v quiet -select_streams ${id} -show_entries stream_tags=comment -of csv=s="|" | awk -F [\|] '{print $2}') # Mise en forme piste vidéo (envoi vers fichier tmp et envoi dans tableau TabYadStream) if [[ "${index}" != "" ]]; then printf "|${iFileIn}|0:${index}|VIDEO|${typeImage}|${codec}|${width}|${height}\n" >> "${dossierTmp}/stream.txt" TabYadStream+=( --field="0:${index} | VIDEO |${typeImage} ${codec} ${width}x${height}":CHK "TRUE") fi else # Mise en forme piste vidéo (envoi vers fichier tmp et envoi dans tableau TabYadStream) if [[ "${index}" != "" ]]; then printf "|${iFileIn}|0:${index}|VIDEO|${codec}|${width}|${height}|${fps}\n" >> "${dossierTmp}/stream.txt" TabYadStream+=( --field="0:${index} | VIDEO |${codec} ${width}x${height} ${fps} fps":CHK "TRUE") fi fi done <<< $(ffprobe -i "${iFileIn}" -hide_banner -v quiet -select_streams v -show_entries stream=index,codec_name,width,height,r_frame_rate -of csv=s="|") } #=========================================================================================================== function STREAMAUDIO() { while read line; do index=$(awk -F [\|] '{print $2}' <<< "${line}") codec=$(awk -F [\|] '{print $3}' <<< "${line}") rate=$(awk -F [\|] '{print $4}' <<< "${line}") channelOut=$(awk -F [\|] '{print $5}' <<< "${line}") lang=$(awk -F [\|] '{print $NF}' <<< "${line}") LANGUE # Affectation TRUE ou FALSE if [[ "${language}" == "${langAudio}" ]] || [[ "${language}" == "Inconnu" ]] || [[ "${langAudio}" == "Toutes les langues" ]]; then bol="TRUE" else bol="FALSE" fi # Mise en forme piste audio (envoi vers fichier tmp et envoi dans tableau TabYadStream) if [[ "${index}" != "" ]]; then printf "|${iFileIn}|0:${index}|AUDIO|${codec}|${language}|${languageISO}|${rate}|${channelOut}|\n" >> "${dossierTmp}/stream.txt" TabYadStream+=( --field="0:${index}| AUDIO | ${language} ${codec} ${rate} Hz ${channelOut}":CHK "${bol}") fi done <<< $(ffprobe -i "${iFileIn}" -hide_banner -v quiet -select_streams a -show_entries stream=index,codec_name,sample_rate,channel_layout,bit_rate -show_entries stream_tags=language -of csv=s="|") } #=========================================================================================================== function STREAMSUBTITLE() { while read line; do index=$(awk -F [\|] '{print $2}' <<< "${line}") codec=$(awk -F [\|] '{print $3}' <<< "${line}") lang=$(awk -F [\|] '{print $NF}' <<< "${line}") LANGUE # Affectation TRUE ou FALSE if [[ "${language}" == "${langSub}" ]] || [[ "${language}" == "Inconnu" ]] || [[ "${langSub}" == "Toutes les langues" ]]; then bol="TRUE" else bol="FALSE" fi # Mise en forme piste audio (envoi vers fichier tmp et envoi dans tableau TabYadStream) if [[ "${index}" != "" ]]; then printf "|${iFileIn}|0:${index}|SUBTITLE|${codec}|${language}|${languageISO}|\n" >> "${dossierTmp}/stream.txt" TabYadStream+=( --field="0:${index} | SUBTITLE | ${language} ${codec}":CHK "${bol}") fi done <<< $(ffprobe -i "${iFileIn}" -hide_banner -v quiet -select_streams s -show_entries stream=index,codec_name -show_entries stream_tags=language -of csv=s="|") } #=========================================================================================================== function PROFIL() { if [[ "${profile}" = "Audio FLAC" ]]; then FLAC conteneur="flac" elif [[ "${profile}" = "Audio vorbis" ]]; then VORBIS conteneur="ogg" elif [[ "${profile}" = "Audio aac" ]]; then AAC conteneur="m4a" elif [[ "${profile}" = "Audio mp3" ]]; then MP3 conteneur="mp3" elif [[ "${profile}" = "Vidéo mkv - x264 - vorbis" ]]; then X264 VORBIS conteneur="mkv" elif [[ "${profile}" = "Vidéo mkv - x264 - aac" ]]; then X264 AAC conteneur="mkv" elif [[ "${profile}" = "Vidéo mkv - x264 - mp3" ]]; then X264 MP3 conteneur="mkv" elif [[ "${profile}" = "Vidéo mkv - x265 - aac" ]]; then X265 AAC conteneur="mkv" elif [[ "${profile}" = "Vidéo mkv - x265 - mp3" ]]; then X265 MP3 conteneur="mkv" fi } #=========================================================================================================== function QUALITY_VIDEO() { # Commande selon la qualité if [[ "${quality}" == "Excellente" ]]; then cdeQualityVideo=(${qVideo1[@]}) elif [[ "${quality}" == "Elevée" ]]; then cdeQualityVideo=(${qVideo2[@]}) elif [[ "${quality}" == "Moyenne" ]]; then cdeQualityVideo=(${qVideo3[@]}) elif [[ "${quality}" == "Minimum" ]]; then cdeQualityVideo=(${qVideo4[@]}) elif [[ "${quality}" == "Faible" ]]; then cdeQualityVideo=(${qVideo5[@]}) fi } #=========================================================================================================== function X265() { if [[ "${codecVideoIn}" = "h265" ]] && [[ "${nocopy}" = "TRUE" ]]; then cVideo="copy" else cVideo="libx265" qVideo1=(-crf 18 -preset slow) qVideo2=(-crf 24 -preset slow) qVideo3=(-crf 30 -preset medium) qVideo4=(-crf 36 -preset veryfast) qVideo5=(-crf 42 -preset ultrafast) fi } #=========================================================================================================== function X264() { if [[ "${codecVideoIn}" = "h264" ]] && [[ "${nocopy}" = "TRUE" ]]; then cVideo="copy" else cVideo="libx264" qVideo1=(-crf 18 -preset slow) qVideo2=(-crf 24 -preset slow) qVideo3=(-crf 30 -preset medium) qVideo4=(-crf 36 -preset veryfast) qVideo5=(-crf 42 -preset ultrafast) fi } #=========================================================================================================== function FLAC() { if [[ "${codecAudioIn}" = "flac" ]] && [[ "${nocopy}" = "TRUE" ]]; then cAudio="copy" else cAudio="flac" fi } #=========================================================================================================== function VORBIS() { if [[ "${codecAudioIn}" = "vorbis" ]] && [[ "${nocopy}" = "TRUE" ]]; then cAudio="copy" else codecAudioOut="vorbis" cAudio="libvorbis" if [[ "${typeRate}" == "VBR" ]]; then qAudio1=(-qscale:a 10) qAudio2=(-qscale:a 8) qAudio3=(-qscale:a 5) qAudio4=(-qscale:a 4) qAudio5=(-qscale:a 0) elif [[ "${typeRate}" == "CBR" ]]; then qAudio1=(-b:a 320k) qAudio2=(-b:a 256k) qAudio3=(-b:a 160k) qAudio4=(-b:a 128k) qAudio5=(-b:a 64k) fi fi } #=========================================================================================================== function AAC() { if [[ "${codecAudioIn}" = "aac" ]] && [[ "${nocopy}" = "TRUE" ]]; then cAudio="copy" else codecAudioOut="aac" cAudio="aac" if [[ "${typeRate}" == "VBR" ]]; then qAudio1=(-q:a 2) qAudio2=(-q:a 1.5) qAudio3=(-q:a 1) qAudio4=(-q:a 0.7) qAudio5=(-q:a 0.2) elif [[ "${typeRate}" == "CBR" ]]; then qAudio1=(-b:a 320k) qAudio2=(-b:a 256k) qAudio3=(-b:a 160k) qAudio4=(-b:a 128k) qAudio5=(-b:a 64k) fi fi } #=========================================================================================================== function MP3() { if [[ "${codecAudioIn}" = "mp3" ]] && [[ "${nocopy}" = "TRUE" ]]; then cAudio="copy" else codecAudioOut="mp3" cAudio="libmp3lame" if [[ "${typeRate}" == "VBR" ]]; then qAudio1=(-q:a 0) qAudio2=(-q:a 1) qAudio3=(-q:a 4) qAudio4=(-q:a 7) qAudio5=(-q:a 9) elif [[ "${typeRate}" == "CBR" ]]; then qAudio1=(-b:a 320k) qAudio2=(-b:a 256k) qAudio3=(-b:a 160k) qAudio4=(-b:a 128k) qAudio5=(-b:a 64k) fi fi } function FFMPEG_SIMPLE { IFS=$'\n' for iFileIn in ${fileIn}; do # Initialisation commandes cdeVideo=() cdeAudio=() cdeSub=() # Nom fichier source fileNameExtension=$(basename "${iFileIn}") fileName="${fileNameExtension%.*}" extension="${fileNameExtension##*.}" STREAMAUDIO cat "${dossierTmp}/stream.txt" exit done } #=========================================================================================================== function FFMPEG() { IFS=$'\n' for iFileIn in ${fileIn}; do # Initialisation commandes cdeVideo=() cdeAudio=() cdeSub=() # Nom fichier source fileNameExtension=$(basename "${iFileIn}") fileName="${fileNameExtension%.*}" extension="${fileNameExtension##*.}" # Recherche map mapVideo=$(awk -v iFileIn="${iFileIn}" -v iMapAudio="${iMapAudio}" -F [\|] '{if ($4 == "VIDEO" && $2 == iFileIn) {printf "%s" ,$3}}' <<< "${stream}") mapAudio=$(awk -v iFileIn="${iFileIn}" -v iMapAudio="${iMapAudio}" -F [\|] '{if ($4 == "AUDIO" && $2 == iFileIn) {printf "%s" ,$3}}' <<< "${stream}") mapSub=$(awk -v iFileIn="${iFileIn}" -v iMapAudio="${iMapAudio}" -F [\|] '{if ($4 == "SUBTITLE" && $2 == iFileIn) {printf "%s" ,$3}}' <<< "${stream}") echo "==============================================" echo " iFileIn: ${iFileIn}" echo " fileName: ${fileName}" echo " mapVideo: ${mapVideo}" echo " mapAudio: ${mapAudio}" echo " mapSub: ${mapSub}" # Metadonnée if [[ "${metadata}" == "TRUE" ]]; then cdeMetadata=(-map_metadata -1) else cdeMetadata=() fi FFMPEG_VIDEO FFMPEG_AUDIO FFMPEG_OUT # Conversion fichier ffmpeg -y -i "${iFileIn}" -loglevel debug "${cdeMetadata[@]}" "${cdeVideo[@]}" "${cdeAudio[@]}" -t 10 "${dirOut}/${fileName}.${conteneur}" ffmpeg -i "${dirOut}/${fileName}.${conteneur}" ## TEST ## echo "==============================================" echo "ffmpeg -y -i ${iFileIn} ${cdeMetadata[@]} ${cdeVideo[@]} ${cdeAudio[@]} -t 10 ${dirOut}/${fileName}.${conteneur} rateTotal: ${rateTotal}" ## TEST ## echo "==============================================" # Image cover fichier audio for iMapVideo in ${mapVideo}; do numImage="1" # Recherche codec vidéo (image) codecVideoIn=$(awk -F [\|] '{if ($4 ~ /VIDEO/ && /'${iMapVideo}'/ && /'${fileName}'/) {printf "%s" ,$5}}' <<< "${stream}") if [[ "${codecVideoIn}" == "mjpeg" ]] || [[ "${codecVideoIn}" == "png" ]]; then COVER fi done done } #=========================================================================================================== function FFMPEG_VIDEO() { numFile="" for iMapVideo in ${mapVideo}; do codecVideoIn=$(awk -v iFileIn="${iFileIn}" -v iMapVideo="${iMapVideo}" -F [\|] '{if ($4 == "VIDEO" && $2 == iFileIn && $3 == iMapVideo){printf "%s" ,$5}}' <<< "${stream}") PROFIL QUALITY_VIDEO if [[ "${profile}" = "Audio FLAC" ]] || [[ "${profile}" = "Audio vorbis" ]] || [[ "${profile}" = "Audio aac" ]] || [[ "${profile}" = "Audio mp3" ]]; then cdeVideo=(-vn) else cdeVideo=(${cdeVideo[@]} -map ${iMapVideo} -c:v ${cVideo} ${cdeQualityVideo[@]}) fi echo "cdeVideo: ${cdeVideo[@]}" done } #=========================================================================================================== function FFMPEG_AUDIO() { numAudio="0" for iMapAudio in ${mapAudio}; do codecAudioIn=$(awk -v iFileIn="${iFileIn}" -v iMapAudio="${iMapAudio}" -F [\|] '{ if ($4 == "AUDIO" && $2 == iFileIn && $3 == iMapAudio) {printf "%s - %s" ,$5,iFileIn} }' <<< "${stream}") languageISO=$(awk -v iFileIn="${iFileIn}" -v iMapAudio="${iMapAudio}" -F [\|] '{ if ($4 == "AUDIO" && $2 == iFileIn && $3 == iMapAudio) {printf "%s" ,$7} }' <<< "${stream}") PROFIL QUALITY_AUDIO cdeAudio=(${cdeAudio[@]} -map ${iMapAudio} -metadata:s:a:${numAudio} language="${languageISO}" -c:a ${cAudio} ${cdeQualityAudio[@]} ${channel[@]} -cutoff 20000) ((numAudio+=1)) done } #=========================================================================================================== function QUALITY_AUDIO() { # Recherche debit total maximum du fichier source rateTotal=$(ffprobe -i "${iFileIn}" -hide_banner -v quiet -show_entries format=bit_rate -of csv=s="|" | awk -F [\|] '{printf "%d\n" ,($2/1000)}') # Commande selon la qualité if [[ "${cAudio}" = "copy" ]] || [[ "${cAudio}" == "flac" ]]; then cdeQualityAudio=() elif [[ "${quality}" == "Excellente" ]]; then if [[ "${rateTotal}" -gt "320" ]]; then cdeQualityAudio=(${qAudio1[@]}) elif [[ "${codecAudioIn}" == "${codecAudioOut}" ]]; then cAudio="copy" cdeQualityAudio=() else cdeQualityAudio=(-b:a "${rateTotal}k") fi elif [[ "${quality}" == "Elevée" ]]; then if [[ "${rateTotal}" -gt "256" ]]; then cdeQualityAudio=(${qAudio2[@]}) elif [[ "${codecAudioIn}" == "${codecAudioOut}" ]]; then cAudio="copy" cdeQualityAudio=() else cdeQualityAudio=(-b:a "${rateTotal}k") fi elif [[ "${quality}" == "Moyenne" ]]; then if [[ "${rateTotal}" -gt "192" ]]; then cdeQualityAudio=(${qAudio3[@]}) elif [[ "${codecAudioIn}" == "${codecAudioOut}" ]]; then cAudio="copy" cdeQualityAudio=() else cdeQualityAudio=(-b:a "${rateTotal}k") fi elif [[ "${quality}" == "Minimum" ]]; then if [[ "${rateTotal}" -gt "128" ]]; then cdeQualityAudio=(${qAudio4[@]}) elif [[ "${codecAudioIn}" == "${codecAudioOut}" ]]; then cAudio="copy" cdeQualityAudio=() else cdeQualityAudio=(-b:a "${rateTotal}k") fi elif [[ "${quality}" == "Faible" ]]; then if [[ "${rateTotal}" -gt "64" ]]; then cdeQualityAudio=(${qAudio5[@]}) elif [[ "${codecAudioIn}" == "${codecAudioOut}" ]]; then cAudio="copy" cdeQualityAudio=() else cdeQualityAudio=(-b:a "${rateTotal}k") fi fi echo "typeRate: ${typeRate}" ## TEST echo "rateTotal: ${rateTotal}" ## TEST echo "quality: ${quality}" ## TEST echo "cdeQualityAudio: ${cdeQualityAudio[@]}" ## TEST } #=========================================================================================================== function FFMPEG_OUT() { # Si fichier exsite déjà ajoute "copie" et numéro de la copie nbrCopie="1" while [[ -f "${dirOut}/${fileName}.${conteneur}" ]]; do fileName=$(awk '{gsub(/ - copie.*/, ""); printf "%s - copie '$nbrCopie'" ,$0}' <<< "${fileName}") ((nbrCopie+=1)) done } #=========================================================================================================== function COVER() { # Si codecVideoIn = mjpeg --> jpeg [[ "${codecVideoIn}" == "mjpeg" ]] && codecVideoIn="jpeg" # Recherche numéro id depuis la map id=$(awk -F [\:] '{print $2}' <<< "${iMapVideo}") # Type d'image (Front, back, other) typeImage=$(ffprobe -i "${i}" -hide_banner -v quiet -select_streams ${id} -show_entries stream_tags=comment -of csv=s="|" | awk -F [\|] '{print $2}') # Nom image cover nameImage=$(ffprobe -i "${i}" -hide_banner -v quiet -select_streams ${id} -show_entries stream_tags=title -of csv=s="|" | awk -F [\|] '{print $2}') if [[ "${nameImage}" == "" ]]; then #nameImage="cover_${typeImage}" if [[ "${typeImage}" == "Cover (front)" ]]; then nameImage="Cover front" elif [[ "${typeImage}" == "Cover (back)" ]]; then nameImage="Cover back" else [[ "${typeImage}" == "Other" ]] nameImage="Other" fi elif [[ "${nameImage}" == "${nameImageSave}" ]]; then nameImage="${nameImage}_${numImage}" fi # Sauvegarde du nom de l'image nameImageSave="${numImage}" ((numImage+=1)) # Extraction image du fichier source ffmpeg -y -i "${iFileIn}" -map ${iMapVideo} -an "${dossierTmp}/${nameImage}.${codecVideoIn}" # Image cover pour fichier audio flac if [[ "${profile}" = "Audio FLAC" ]]; then COVER_FLAC # Image cover pour fichier audio vorbis elif [[ "${profile}" = "Audio vorbis" ]]; then COVER_OGG # Image cover pour fichier audio mp3 elif [[ "${profile}" = "Audio mp3" ]]; then COVER_MP3 # Image cover pour fichier audio aac elif [[ "${profile}" = "Audio aac" ]]; then COVER_OTHER fi echo "=== COVER ===" echo "id: ${id}" echo "typeImage: ${typeImage}" echo "nameImage: ${nameImage}" } #=========================================================================================================== function COVER_FLAC() { if [[ "${typeImage}" == "Cover (front)" ]]; then typeImage="3" elif [[ "${typeImage}" == "Cover (back)" ]]; then typeImage="4" else [[ "${typeImage}" == "Other" ]] typeImage="0" fi # Ajout de l'image au fichier audio metaflac --import-picture-from="${typeImage}||${nameImage}||${dossierTmp}/${nameImage}.${codecVideoIn}" "${dirOut}/${fileName}.${conteneur}" } #=========================================================================================================== function COVER_OGG() { # Type d'image (Front, back, other) typeImage=$(ffprobe -i "${i}" -hide_banner -v quiet -select_streams ${id} -show_entries stream_tags=comment -of csv=s="|" | awk -F [\|] '{print $2}') if [[ "${typeImage}" == "Cover (front)" ]]; then typeImage="3" elif [[ "${typeImage}" == "Cover (back)" ]]; then typeImage="4" elif [[ "${typeImage}" == "Artist/performer" ]]; then typeImage="8" elif [[ "${typeImage}" == "Other" ]]; then typeImage="0" else typeImage="3" fi # Sauvegarde données exsistantes du fichier source vorbiscomment --list --raw "${dirOut}/out.${conteneur}" > "${dossierTmp}/fileSaveOgg.txt" #Suppression image exsistante #sed -i -e '/^metadata_block_picture/d' "${dossierTmp}/fileSaveOgg.txt" # Metadata_block_picture format #Lien: https://xiph.org/flac/format.html#metadata_block_picture imageMimeType=$(file -b --mime-type "${dossierTmp}/${nameImage}.${codecVideoIn}") printf "0: %.8x" "${typeImage}" | xxd -r -g0 >> "${dossierTmp}/dataImage.txt" printf "0: %.8x" $(echo -n "${imageMimeType}" | wc -c) | xxd -r -g0 >> "${dossierTmp}/dataImage.txt" echo -n "${imageMimeType}" >> "${dossierTmp}/dataImage.txt" printf "0: %.8x" $(echo -n "${nameImage}" | wc -c) | xxd -r -g0 >> "${dossierTmp}/dataImage.txt" echo -n "${nameImage}" >> "${dossierTmp}/dataImage.txt" printf "0: %.8x" 0 | xxd -r -g0 >> "${dossierTmp}/dataImage.txt" printf "0: %.8x" 0 | xxd -r -g0 >> "${dossierTmp}/dataImage.txt" printf "0: %.8x" 0 | xxd -r -g0 >> "${dossierTmp}/dataImage.txt" printf "0: %.8x" 0 | xxd -r -g0 >> "${dossierTmp}/dataImage.txt" printf "0: %.8x" $(wc -c "${dossierTmp}/cover.${codecVideoIn}" | cut --delimiter=' ' --fields=1) | xxd -r -g0 >> "${dossierTmp}/dataImage.txt" #Image file cat "${dossierTmp}/cover.${codecVideoIn}" >> "${dossierTmp}/dataImage.txt" echo "metadata_block_picture=$(base64 --wrap=0 < "${dossierTmp}/dataImage.txt")" >> "${dossierTmp}/fileSaveOgg.txt" #Update vorbis file comments vorbiscomment --write --raw --commentfile "${dossierTmp}/fileSaveOgg.txt" "${dirOut}/${fileName}.${conteneur}" #Delete temp files rm "${dossierTmp}/dataImage.txt" rm "${dossierTmp}/fileSaveOgg.txt" } #=========================================================================================================== function COVER_MP3() { if [[ "${typeImage}" == "Cover (front)" ]]; then typeImage="FRONT_COVER" elif [[ "${typeImage}" == "Cover (back)" ]]; then typeImage="BACK_COVER" elif [[ "${typeImage}" == "Artist/performer" ]]; then typeImage="ARTIST" elif [[ "${typeImage}" == "Other" ]]; then typeImage="OTHER" else typeImage="FRONT_COVER" fi # Ajout de l'image au fichier audio eyeD3 --add-image="${dossierTmp}/${nameImage}.${codecVideoIn}":"${typeImage}":"${nameImage}" "${dirOut}/${fileName}.${conteneur}" } #=========================================================================================================== function COVER_OTHER() { if [[ "${typeImage}" == "Cover \(back\)" ]]; then # renommage image cover en "cover" mv "${dossierTmp}/${nameImage}.${codecVideoIn}" "${dossierTmp}/cover.${codecVideoIn}" # Ajout de l'image au fichier audio kid3-cli -c "set picture:"${dossierTmp}/cover.${codecVideoIn}" ''" "${dirOut}/${fileName}.${conteneur}" fi } #=========================================================================================================== function MAIN() { # Chargement fichier de configurations . "${fileConfig}" YADMAIN # Si aucune source sélectionnée if [[ "${status}" -eq "0" ]] && [[ "${fileIn}" == "" ]]; then status="4" fi # YADMAIN Bouton "Quitter" ou "Croix fenêtre" if [[ "${status}" -eq "1" ]] || [[ "${status}" -eq "252" ]]; then rm -rf "${dossierTmp}" exit # YADMAIN Bouton "Configuration par défaut" elif [[ "${status}" -eq "3" ]]; then SAVE CONFIGDEFAUT MAIN # YADMAIN Bouton "Préférences" elif [[ "${status}" -eq "2" ]]; then SAVE YADPREFERENCE # YADPREFERENCE Bouton "Quitter" ou "Croix fenêtre" if [[ "${status}" -eq "1" ]] || [[ "${status}" -eq "252" ]]; then rm -rf "${dossierTmp}" exit # YADPREFERENCE Bouton "Annuler" elif [[ "${status}" -eq "2" ]]; then MAIN # YADPREFERENCE Bouton "Valider" elif [[ "${status}" -eq "0" ]]; then SAVE MAIN fi # YADMAIN Bouton "Source" ou aucune source sélectionnée elif [[ "${status}" -eq "4" ]]; then SAVE YADSOURCE # YADSOURCE Bouton "Quitter" ou "Croix fenêtre" if [[ "${status}" -eq "1" ]] || [[ "${status}" -eq "252" ]]; then rm -rf "${dossierTmp}" exit # YADSOURCE Bouton "Annuler" elif [[ "${status}" -eq "2" ]]; then MAIN # YADSOURCE choix "Fichier avec analyse" elif [[ "${source}" == "Fichier avec analyse" ]]; then YADFILE # Si dossier selectionner, liste les fichiers contenu du dossier [[ -d "${fileIn}" ]] && fileIn=$(ls "${fileIn}"/*) # YADFILE Bouton "Quitter" ou "Croix fenêtre" if [[ "${status}" -eq "1" ]] || [[ "${status}" -eq "252" ]]; then rm -rf "${dossierTmp}" exit # YADFILE Bouton "Annuler" elif [[ "${status}" -eq "2" ]]; then MAIN # YADFILE Bouton "Valider" elif [[ "${status}" -eq "0" ]]; then STREAM | YADPROGRESS IFS=$'\n' TabYadStream=($(cat "${dossierTmp}/yadStream.txt")) rm "${dossierTmp}/yadStream.txt" MAIN fi # YADSOURCE choix "Fichier" elif [[ "${source}" == "Fichier" ]]; then YADFILE # Si dossier selectionner, liste les fichiers contenu du dossier [[ -d "${fileIn}" ]] && fileIn=$(ls "${fileIn}"/*) # YADFILE Bouton "Quitter" ou "Croix fenêtre" if [[ "${status}" -eq "1" ]] || [[ "${status}" -eq "252" ]]; then rm -rf "${dossierTmp}" exit # YADFILE Bouton "Annuler" elif [[ "${status}" -eq "2" ]]; then MAIN # YADFILE Bouton "Valider" elif [[ "${status}" -eq "0" ]]; then STREAM_SIMPLE | YADPROGRESS IFS=$'\n' TabYadStream=($(cat "${dossierTmp}/yadStream.txt")) rm "${dossierTmp}/yadStream.txt" MAIN fi # YADSOURCE choix "DVD" elif [[ "${source}" == "DVD" ]]; then echo "Source DVD à finir" # YADSOURCE choix "CD" elif [[ "${source}" == "CD" ]]; then echo "Source CD à finir" # YADSOURCE choix "DDL" elif [[ "${source}" == "DDL" ]]; then echo "Source DDL à finir" fi # YADMAIN Bouton "Lancer conversion" elif [[ "${status}" -eq "0" ]]; then SAVE if [[ "${source}" == "Fichier avec analyse" ]]; then # Récupération de la valeur TRUE et FALSE depuis YADMAIN et fusion avec les données du fichier stream.txt IFS=$"|" numLine="4" # Ligne 4 première ligne avec valeur TRUE ou FALSE stream=$( while read line; do bol=$(awk 'NR == '${numLine}' {printf "%s" ,$1}' <<< "$(printf "%s\n" ${yadMain} | awk NF)") printf "${bol}${line}\n" ((numLine+=1)) done <<< $(cat "${dossierTmp}/stream.txt") | awk -F [\|] '{if ($1 ~ /TRUE/) {print $0}}') SAVE FFMPEG MAIN elif [[ "${source}" == "Fichier" ]]; then SAVE FFMPEG_SIMPLE MAIN fi fi } #=========================================================================================================== CONFIGURATION #fileIn="/home/$USER/Bureau/0in.m4a" ## TEST #STREAM ## TEST MAIN