Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 29/07/2008, à 17:13

Goldy

[Résolu] [Shell] Extraire une chaine de caractère d'une variable

Bonjour,

Je suis en train de créer un script shell qui aura pour but de convertir des vidéos pour mon appareil mobile. Je débute activement en scripting shell, donc la question va certainement sembler très n00bs je pense.

J'ai été face à un problème dont je n'ai pas trouvé de solution mais que j'ai réussi à contourner. Malgré tout, je suis frustré de pas être parvenu à faire ce que je voulais.

Il s'agit du premier module de mon script qui aura pour usage de définir quel type de conteneur est utilisé dans la vidéo à convertir. Pour y arriver, j'ai utilisé la commande file qui me permet d'avoir des informations sur un fichier, j'ai ensuite définit des variables qui me permettent de comparer les résultats de la commande file.

J'ai eu un soucis pour les fichiers OGM car la commande file va me donner un résultat différents d'un fichier ogm à un autre en fonction du codec vidéo utilisé. J'avais donc besoin d'extraire de la variable définit par la commande file la chaine de caractère qui m'intéressait. Or je ne trouve pas de moyen d'y parvenir, je pensais utiliser expr match, mais je n'ai pas trouvé de moyens d'y arriver.

J'ai contourné le problème en utilisant expr substr qui extrait les caractères en fonction de leurs positions dans la chaine, mais je pense que ça pourrait poser un soucis au cas où le début de la chaine de caractère venait à varier.

Je poste le code (qui pour l'instant ne fait qu'afficher quel type de conteneur est utilisé).

#!/bin/sh

#test pour définition du type MIME des fichiers


#définition de la variable
original="$1"

#commande mime et types
mime="`file -ib "$original"`" #sort le type MIME du fichier
types="`file -b "$original"`" #sort une description du fichier

#type de fichier
mpeg="video/mpeg"
avi="video/x-msvideo"
mp4="video/mp4"
mkv="Matroska data"
flv="Macromedia Flash Video"
ogm="OGM video"

#Exeption fichiers ogm
ogm_types="`expr substr "$types" 11 9`" #extraction des 9 caractères suivant la 11ème colonne de la variable $types.

###boucle de détection

#debugage
#echo "La valeur mime est $mime"
#echo "La valeur types est $types"
#echo "La valeur de ogm_types est $ogm_types"

#Video MPEG
if test "$mime" = "$mpeg"
	then echo "Le conteneur de cette vidéo est au format MPEG"

#Video AVI
elif test "$mime" = "$avi"
	then echo "Le conteneur de cette vidéo est au format AVI"

#Video MP4
elif test "$mime" = "$mp4"
	then echo "Le conteneur de cette vidéo est au format MP4"

#Video MKV
elif test "$types" = "$mkv"
	then echo "Le conteneur de cette vidéo est au format MKV"

#Video FLV
elif test "$types" = "$flv"
	then echo "Le conteneur de cette vidéo est au format FLV"

#Video OGM
elif test "$ogm_types" = "$ogm"
	then echo "Le conteneur de cette vidéo est au format OGM"

#Non pris en charge
else echo "Le conteneur de cette vidéo n'est pas pris en charge par le script"

fi

(mon premier code :D )

Dernière modification par Goldy (Le 10/08/2008, à 23:16)

Hors ligne

#2 Le 29/07/2008, à 18:17

Link31

Re : [Résolu] [Shell] Extraire une chaine de caractère d'une variable

Tu peux t'inspirer de ça :

#!/bin/bash
case `file -ib "$1"` in
        *mp4*)
                echo mp4
                ;;

        *flv*)
                echo flash
                ;;

        *)
                echo autre
                ;;
esac

Hors ligne

#3 Le 29/07/2008, à 18:20

#hehedotcom\'isback

Re : [Résolu] [Shell] Extraire une chaine de caractère d'une variable

Link31 a écrit :

Tu peux t'inspirer de ça :

#!/bin/bash
case `file -ib "$1"` in
        *mp4*)
                echo mp4
                ;;

        *flv*)
                echo flash
                ;;

        *)
                echo autre
                ;;
esac

C'est moins compliqué lol
t'es baleze, respect big_smile


../

Hors ligne

#4 Le 29/07/2008, à 23:20

Goldy

Re : [Résolu] [Shell] Extraire une chaine de caractère d'une variable

Link31 a écrit :

Tu peux t'inspirer de ça :

#!/bin/bash
case `file -ib "$1"` in
        *mp4*)
                echo mp4
                ;;

        *flv*)
                echo flash
                ;;

        *)
                echo autre
                ;;
esac

Ha effectivement, case permet une meilleur souplesse que if. Je pensais l'utiliser par la suite mais je n'avais pas encore exploré les possibilités. J'avais essayé de mettre des jokers dans if, je n'arrivais à rien.

Merci pour ta réponse.

Hors ligne

#5 Le 29/07/2008, à 23:48

nicolas66

Re : [Résolu] [Shell] Extraire une chaine de caractère d'une variable

Un ptit résolu ? smile


"The computer was born to solve problems that did not exist before." (B. Gates)

Hors ligne

#6 Le 30/07/2008, à 17:10

Goldy

Re : [Résolu] [Shell] Extraire une chaine de caractère d'une variable

J'ai adapté le script, je le poste pour ceux qui serait intéressé.

#!/bin/bash

#mime 2

#Amélioration du script de détection du type de conteneur vidéo.

#définition de la variable du nom de la vidéo
original="$1"

#Définition de la variable sur la sortie de la commande "file"
file_type="`file -b "$original"`"

###boucle de détection

case "$file_type" in

#Video MPEG
	*"MPEG sequence"*)
		conteneur="MPEG"
		;;		

#Video AVI
	*"AVI"*)
		conteneur="AVI"
		;;		
#Video MP4
	*"MPEG v4 system"*)
		conteneur="MP4"
		;;		

#Video MKV
	*"Matroska data"*)
		conteneur="MKV"
		;;		

#Video FLV
	*"Macromedia Flash Video"*)
		conteneur="FLV"
		;;		

#Video OGM
	*"OGM video"*)
		conteneur="OGM"
		;;		
esac

#Debug
#echo "$conteneur"

#Affichage du conteneur
case "$conteneur" in
	MPEG|AVI|MP4|MKV|FLV|OGM)
		echo "Le conteneur de cette vidéo est au format $conteneur"
		;;
#Fichiers non pris en charge	
	*)
		echo "Le fichier n'est pas pris en charge par le script"
		;;

esac

Hors ligne

#7 Le 02/08/2008, à 15:10

Goldy

Re : [Résolu] [Shell] Extraire une chaine de caractère d'une variable

Juste une petite précision, j'ai ajouté [Résolu] alors que le problème avait simplement été contourné mais pas résolu.

Je viens d'avoir ce problème alors que je devais utiliser la commande while, et j'ai trouvé la solution en potassant le Guide avancé d'écriture des scripts Bash (disponible ici : http://abs.traduc.org/ )

En fait, il faut utiliser la commande echo et grep avec un tuyaux. Par exemple le code que j'ai écrit qui permet de savoir combien de piste il y a dans un fichier MKV.

#définition des variables
original=$1


#définition de la sortie des commandes mkvinfo et mkvmerge -i
var_mkvinfo="`mkvinfo "$original"`"
var_mkvmerge="`mkvmerge -i "$original"`"

#Variable n
n=1

#À la recherche du nombre de piste...

while echo "$var_mkvmerge" | grep -q "ID $n"
 do
	n=$(($n + 1))
done

#Soustraction de la valeur en trop
n=$(($n - 1))

#Affichage du nombre de pistes du fichier mkv

echo "Le fichier MKV contient $n piste(s)"

On remarquera

while echo "$var_mkvmerge" | grep -q "ID $n"

Ce code permet d'extraire de la valeur $var_mkvmerge la chaine de caractère ID $n ($n étant un nombre entier définit par le script et la boucle while).

Bien entendu, cela fonctionne avec while, if et until.

Voilà, je pense que cette info peut aider certain débutant en scriptage, car j'ai mis un petit moment avant de comprendre cette ligne que j'avais pourtant lu un paquet de fois dans le guide.

Hors ligne

#8 Le 02/08/2008, à 22:01

Alain.g

Re : [Résolu] [Shell] Extraire une chaine de caractère d'une variable

Goldy a écrit :

Par exemple le code que j'ai écrit qui permet de savoir combien de piste il y a dans un fichier MKV.

Bonsoir

Tu peux plus simplement utiliser l'option -c de grep.
Par exemple on compte le lignes commençant pas "Track" :

n=$(grep -c '^Track' <<< "$var_mkvmerge")

ou sans basherie

n=`echo "$var_mkvmerge" | grep -c '^Track'`

Dernière modification par Alain.g (Le 02/08/2008, à 22:08)


Xubuntu Karmic !

Hors ligne

#9 Le 02/08/2008, à 22:29

Goldy

Re : [Résolu] [Shell] Extraire une chaine de caractère d'une variable

Alain.g a écrit :
Goldy a écrit :

Par exemple le code que j'ai écrit qui permet de savoir combien de piste il y a dans un fichier MKV.

Bonsoir

Tu peux plus simplement utiliser l'option -c de grep.
Par exemple on compte le lignes commençant pas "Track" :

n=$(grep -c '^Track' <<< "$var_mkvmerge")

ou sans basherie

n=`echo "$var_mkvmerge" | grep -c '^Track'`

Oui, je l'ai découvert un peu après quand il a fallut que je fasse le détail du nombre de piste audio, vidéo et de sous-titres.

Le truc étant de traiter automatiquement les pistes en fonction de leurs attribues tel que la langue.

Maintenant, je suis bloqué pour identifier l'emplacement des différentes pistes. Ce qui me gêne, c'est le fait que le nombre de variable à définir va dépendre directement du nombre de piste, et je ne sais pas comment mettre ça en œuvre.

Par exemple, sur une vidéo de 5 pistes, je repère 2 pistes de sous-titres, j'ai besoin de définir où ce trouve ces deux pistes pour savoir quelle piste sera encodé dans la vidéo, et c'est là que ça bloque dans mon petit cerveau.

Dans la première version de mon code, j'avais pondu ça :

#!/bin/sh


#Script d'analyse de flux de fichier mkv


###Définition des variables

original="$1"

#variable de la sortie de mkvinfo
var_mkvinfo="`mkvinfo "$original"`"

#Pour pas avoir d'erreurs
un=un
deux=deux
trois=trois


#vérification du nombre de pistes

#3 pistes
case "$var_mkvinfo" in
	*"Track number: 3"*)
		number_track=trois
		;;
esac

if test "$number_track" = "$trois"

	then echo "Le fichier MKV contient 3 pistes différentes"

else
		case "$var_mkvinfo" in
			*"Track number: 2"*)
				number_track=deux
			;;
		esac
fi


#2 pistes

if test "$number_track" = "$deux"

	then echo "Le fichier MKV contient 2 pistes différentes"

elif test "$number_track" = "$trois"

	then 
	nothing=0 #ce truc est à régler

else
		case "$var_mkvinfo" in
			*"Track number: 1"*)
				number_track=un
			;;
		esac
fi


#1 pistes et erreurs
if test "$number_track" = "$un"

	then echo "Le fichier MKV ne contient qu'une piste"

elif test "$number_track" = "$trois"
	then
	nothing=0 #ce truc est à régler
elif test "$number_track" = "$deux"

	then
	nothing=0 #ce truc est à régler
else
	echo "Il doit y avoir un problème avec ce fichier MKV, il ne semble contenir aucune piste"	

fi
# Ça marche et je suis content


###Analyse du contenu des flux

#MKV à une piste
if test "$number_track" = "$un"
	then
		case "$var_mkvinfo" in
			*"Track type: video"*)
				track_un="video"
			;;
			
			*"Track type: audio"*)
				track_un="audio"
			;;

			*"Track type: subtitles"*)
				track_un="subtitles"
			;;
		esac

#MKV à deux pistes
elif test "$number_track" = "$deux"
	then
		case "$var_mkvinfo" in
		#Dans le cas où la seconde piste est une piste vidéo
			*"Track number: 2"*"Track type: video"*)
				track_deux="video"
					#Imbrication d'une troisième boucle pour tester la première piste
						case "$var_mkvinfo" in
							*"Track type: video"*"Track type: video"*)
								track_un="video"
							;;
							*"Track type: audio"*"Track type: video"*)
								track_un="audio"
							;;
							*"Track type: subtitles"*"Track type: video"*)
								track_un="subtitles"
							;;
						esac
					#Fin de la boucle
							
			;;

		#Dans le cas où la seconde piste est une piste audio
			*"Track number: 2"*"Track type: audio"*)
				track_deux="audio"
					#Imbrication d'une troisième boucle pour tester la première piste
						case "$var_mkvinfo" in
							*"Track type: video"*"Track type: audio"*)
								track_un="video"
							;;
							*"Track type: audio"*"Track type: audio"*)
								track_un="audio"
							;;
							*"Track type: subtitles"*"Track type: audio"*)
								track_un="subtitles"
							;;
						esac
					#Fin de la boucle
			;;

		#Dans le cas où la seconde piste est une piste de sous-titres
			*"Track number: 2"*"Track type: subtitles"*)
				track_deux="subtitles"
					#Imbrication d'une troisième boucle pour tester la première piste
						case "$var_mkvinfo" in
							*"Track type: video"*"Track type: subtitles"*)
								track_un="video"
							;;
							*"Track type: audio"*"Track type: subtitles"*)
								track_un="audio"
							;;
							*"Track type: subtitles"*"Track type: subtitles"*)
								track_un="subtitles"
							;;
						esac
					#Fin de la boucle
			;;
		esac

#MKV à trois pistes
elif test "$number_track" = "$trois"
	then
		case "$var_mkvinfo" in
		#Dans le cas où la troisième piste est une piste vidéo
			*"Track number: 3"*"Track type: video"*)
				track_trois="video"
					#Imbrication d'une troisième boucle pour tester les deux premières pistes
						case "$var_mkvinfo" in
							#Piste 2 est de la vidéo
							*"Track type: video"*"Track type: video"*"Track type: video"*)
								track_un="video"
								track_deux="video"
							;;
							*"Track type: audio"*"Track type: video"*"Track type: video"*)
								track_un="audio"
								track_deux="video"
							;;
							*"Track type: subtitles"*"Track type: video"*"Track type: video"*)
								track_un="subtitles"
								track_deux="video"
							;;
							#Piste 2 est de l'audio
							*"Track type: video"*"Track type: audio"*"Track type: video"*)
								track_un="video"
								track_deux="audio"
							;;
							*"Track type: audio"*"Track type: audio"*"Track type: video"*)
								track_un="audio"
								track_deux="audio"
							;;
							*"Track type: subtitles"*"Track type: audio"*"Track type: video"*)
								track_un="subtitles"
								track_deux="audio"
							;;
							#Piste 2 sont des sous-titres
							*"Track type: video"*"Track type: subtitles"*"Track type: video"*)
								track_un="video"
								track_deux="subtitles"
							;;
							*"Track type: audio"*"Track type: subtitles"*"Track type: video"*)
								track_un="audio"
								track_deux="subtitles"
							;;
							*"Track type: subtitles"*"Track type: subtitles"*"Track type: video"*)
								track_un="subtitles"
								track_deux="subtitles"
							;;
						esac
					#Fin de la boucle
				;;
		#Dans le cas où la troisième piste est une piste audio
			*"Track number: 3"*"Track type: audio"*)
				track_trois="audio"
					#Imbrication d'une troisième boucle pour tester les deux premières pistes
						case "$var_mkvinfo" in
							#Piste 2 est de la vidéo
							*"Track type: video"*"Track type: video"*"Track type: audio"*)
								track_un="video"
								track_deux="video"
							;;
							*"Track type: audio"*"Track type: video"*"Track type: audio"*)
								track_un="audio"
								track_deux="video"
							;;
							*"Track type: subtitles"*"Track type: video"*"Track type: audio"*)
								track_un="subtitles"
								track_deux="video"
							;;
							#Piste 2 est de l'audio
							*"Track type: video"*"Track type: audio"*"Track type: audio"*)
								track_un="video"
								track_deux="audio"
							;;
							*"Track type: audio"*"Track type: audio"*"Track type: audio"*)
								track_un="audio"
								track_deux="audio"
							;;
							*"Track type: subtitles"*"Track type: audio"*"Track type: audio"*)
								track_un="subtitles"
								track_deux="audio"
							;;
							#Piste 2 sont des sous-titres
							*"Track type: video"*"Track type: subtitles"*"Track type: audio"*)
								track_un="video"
								track_deux="subtitles"
							;;
							*"Track type: audio"*"Track type: subtitles"*"Track type: audio"*)
								track_un="audio"
								track_deux="subtitles"
							;;
							*"Track type: subtitles"*"Track type: subtitles"*"Track type: audio"*)
								track_un="subtitles"
								track_deux="subtitles"
							;;
						esac
					#Fin de la boucle
				;;
		#Dans le cas où la troisième piste est une piste de sous-titres
			*"Track number: 3"*"Track type: subtitles"*)
				track_trois="subtitles"
					#Imbrication d'une troisième boucle pour tester les deux premières pistes
						case "$var_mkvinfo" in
							#Piste 2 est de la vidéo
							*"Track type: video"*"Track type: video"*"Track type: subtitles"*)
								track_un="video"
								track_deux="video"
							;;
							*"Track type: audio"*"Track type: video"*"Track type: subtitles"*)
								track_un="audio"
								track_deux="video"
							;;
							*"Track type: subtitles"*"Track type: video"*"Track type: subtitles"*)
								track_un="subtitles"
								track_deux="video"
							;;
							#Piste 2 est de l'audio
							*"Track type: video"*"Track type: audio"*"Track type: subtitles"*)
								track_un="video"
								track_deux="audio"
							;;
							*"Track type: audio"*"Track type: audio"*"Track type: subtitles"*)
								track_un="audio"
								track_deux="audio"
							;;
							*"Track type: subtitles"*"Track type: audio"*"Track type: subtitles"*)
								track_un="subtitles"
								track_deux="audio"
							;;
							#Piste 2 sont des sous-titres
							*"Track type: video"*"Track type: subtitles"*"Track type: subtitles"*)
								track_un="video"
								track_deux="subtitles"
							;;
							*"Track type: audio"*"Track type: subtitles"*"Track type: subtitles"*)
								track_un="audio"
								track_deux="subtitles"
							;;
							*"Track type: subtitles"*"Track type: subtitles"*"Track type: subtitles"*)
								track_un="subtitles"
								track_deux="subtitles"
							;;
						esac
					#Fin de la boucle
			;;

		esac
#Cas d'erreur
else
		echo "Le fichier MKV ne peut malheureusement pas être traité par ce script"

fi



#Affichage du détail de l'analyse

if test "$number_track" = "$un"
	then
		echo "Piste 1 : $track_un"

elif test "$number_track" = "$deux"
	then
		echo "Piste 1 : $track_un"
		echo "Piste 2 : $track_deux"

elif test "$number_track" = "$trois"
	then
		echo "Piste 1 : $track_un"
		echo "Piste 2 : $track_deux"
		echo "Piste 3 : $track_trois"

fi

#Ça a marché du premier coup ^o^

Totalement imbuvable comme script, mais fonctionnel (je l'avais écrit sans connaitre la commande mkvmerge -i). Le truc étant que ça ne fonctionne que pour une vidéo contenant 3 pistes, et dans mon hélant de perfectude, j'ai envie de réaliser une fonction capable d'identifier les pistes à traiter en fonction de leurs attributs, et donc de pouvoir accepter les fichiers mkv quelque soit leur nombre de pistes.

Dernière modification par Goldy (Le 02/08/2008, à 22:34)

Hors ligne

#10 Le 03/08/2008, à 11:23

Alain.g

Re : [Résolu] [Shell] Extraire une chaine de caractère d'une variable

Je n'ai pas très bien saisi la façon dont tu veux procéder, mais ce qui pourrait t'aider, c'est d'utiliser mkvmerge -I video.mkv avec un i majuscule au lieu du minuscule : ça te donnerait les attributs essentiels comme la langue et du coup tu pourras facilement avoir les ID des pistes qui t'intéressent.


Xubuntu Karmic !

Hors ligne

#11 Le 03/08/2008, à 16:01

Goldy

Re : [Résolu] [Shell] Extraire une chaine de caractère d'une variable

Ha, merci pour l'info, je ne savais pas pour mkvmerge -I. Mais c'est pas vraiment là où se situe la difficulté, je ne sais pas non plus trop de quelle façon je vais procéder d'ailleurs.

De toute façon, je pense que je vais abandonner pour l'instant cette idée qui semble au delà de mes capacités actuelles (ça fait qu'une petite semaine que je découvre la programmation shell, et encore pleins de points sont obscures à mes yeux, j'en apprends à chaque ligne que j'écris). J'ai arrangé la première version du script qui permet d'identifier 3 pistes dans un fichiers mkv, et la règle est que le script peu traiter un fichier mkv à 3 pistes maximum, et les 3 pistes doivent être différentes.

Voilà où j'en suis :

#!/bin/sh

#programme d'encodage vidéo pour apareil mobile.
#Encode tout type de vidéo au format h264/aac dans un conteneur mkv, avec une taille adaptée à un écran de 320*240 pixel.
#WORK IN PROGRESS
#Copyright Goldy <goldy[at]goldenfish[point]info> - Licence GPL 3.0

##############################
## Définition des variables ##
##############################


original="${1##*/}" #Nom du fichier
original_test=""$original"/" #Pour eviter le message d'erreur lors du test
dir_original="${1%/*}/" #Répertoire vers le fichier
error=0 #Initialisation du controle d'erreur

## Debugage ##

#echo "dir_original : "$dir_original""

###################################
## Accès aux dossiers de travail ##
###################################

testing_dir () {

#Vérifie que le fichier est dans un répertoire distant ou non
if [ "$dir_original" != "$original_test" ]
	then 
		echo "Le fichier est situé dans un répertoire distant".
		#Pénètre le répertoire distant
		if cd "$dir_original"
			then
				echo "Pénètre le répertoire de la vidéo \"$dir_original\""
					#Vérifie la non présence du fichier
					if [ ! -f "$original" ]
						then
							echo "Le fichier n'existe pas dans le répertoire distant"
							error=1
					fi
		else
			echo "Impossible d'accéder au répertoire"
			error=1
		fi
else
	#Le fichier est dans le répertoire courant, tester sa présence
	if [ ! -f "$original" ]
		then
			echo "Le fichier n'existe pas dans le répertoire distant"
			error=1
	fi
fi
}

#######################################
## Création des fichiers temporaires ##
#######################################




# Fonction copie temporaire #
#############################


tmp_create () {

#variables
tmp_dir=""$original"_tmp"
copy=""$tmp_dir"/"$original""

wc_original="`wc -l "$original"`"
wc_copy="`wc -l "$copy"`"

size_original="`expr match "$wc_original" '\([1-9]\)'`"
size_copy="`expr match "$wc_copy" '\([1-9]\)'`"



#teste la présence du dossier temporaire
if [ ! -d "$tmp_dir" ]
	then
		#Créer le dossier temporaire
		if mkdir "$tmp_dir"
			then echo "Création du dossier temporaire"

		else 
			echo "Une erreur s'est produite lors de la création du dossier temporaire"
			error=1
		fi
else
	echo "Le répertoire temporaire existe déjà"
fi


#Copie de la vidéo dans le dossier temporaire

#Vérifie l'absence d'erreur
if [ "$error" -eq "0" ]
	then
		#Vérifie la présence d'un fichier dans le dossier temporaire
		if [ -e "$copy" ]
			then
				echo "La copie du fichier semble avoir été déjà effectuée"
				#Vérifie que les fichiers sont bien identiques
				if test "$size_original" = "$size_copy"
					then
						echo "Et c'est le cas"
				else
					echo "Mais les deux fichiers ont une taille différente"
					#Efface de fichier temporaire corrompu
					if rm "$copy"
						then
							echo "Le fichier temporaire a été effacé et va être copié à nouveaux"
								#Copie du fichier dans le dossier temporaire
								if cp "$original" "$copy"
									then echo "La copie a été effectuée avec succès"
								else
									echo "Une erreur s'est produite lors de la copie du fichier"
									error=1
								fi
					else
						echo "Impossible de suprimer le fichier"
						error=1
					fi
				fi
		else
			echo "Copie de la vidéo dans le dossier temporaire..."
			#Copie du fichier dans le dossier temporaire
			if cp "$original" "$copy"
				then echo "La copie a été effectuée avec succès"
			else
				echo "Une erreur s'est produite lors de la copie du fichier"
				error=1
			fi
		fi
		
else
	echo "Une erreur s'est produite : intéruption"
fi


#Pénètre dans le dossier temporaire
if cd "$tmp_dir"/
	then echo "Pénètre dans le dossier temporaire"
		
	#Vérifie la présence du fichier
	if test -e "$copy"
	
	then
		echo "Le fichier vidéo ne semble pas présent dans le dossier temporaire : abandon"
		error=1
	fi

else
	echo "Le dossier temporaire n'existe pas"
	error=1
fi
}



# Fonction création MKV #
#########################
tmp_create_mkv () {

#variables
tmp_dir=""$original"_tmp"
copy=""$tmp_dir"/"$original""


#teste la présence du dossier temporaire
if [ ! -d "$tmp_dir" ]
	then
		#Créer le dossier temporaire
		if mkdir "$tmp_dir"
			then echo "Création du dossier temporaire"

		else 
			echo "Une erreur s'est produite lors de la création du dossier temporaire"
			error=1
		fi
else
	echo "Le répertoire temporaire existe déjà"
fi


#Copie de la vidéo dans le dossier temporaire

#Vérifie l'absence d'erreur
if [ "$error" -eq "0" ]
	then
		#Vérifie la présence d'un fichier dans le dossier temporaire
		if [ -e "$copy" ]
			then
				echo "La conversion du fichier semble avoir été déjà effectuée, il va être effacé"

					#Efface de fichier temporaire
					if rm "$copy"
						then
							echo "Le fichier temporaire a été effacé et va être à nouveau convertie"
								#Copie du fichier dans le dossier temporaire
								if mkvmerge --no-chapters -o "$copy" "$original"
									then echo "La convertion en MKV a été effectuée avec succès"
								else
									echo "Une erreur semble s'être produite lors de la conversion du fichier"
								fi
					else
						echo "Impossible de supprimer le fichier"
						error=1
					fi
		else
			echo "Convertion de la vidéo dans le dossier temporaire..."
			#Conversion du fichier dans le dossier temporaire
			if mkvmerge --no-chapters -o "$copy" "$original"
				then echo "La convertion a été effectuée avec succès"
			else
				echo "Une erreur semble s'être produite lors de la conversion du fichier"
			fi
		fi
		
else
	echo "Une erreur s'est produite : interruption"
fi


#Pénètre dans le dossier temporaire
if cd "$tmp_dir"/
	then echo "Pénètre dans le dossier temporaire"
		
	#Vérifie la présence du fichier
	if test -e "$copy"
	
	then
		echo "Le fichier vidéo ne semble pas présent dans le dossier temporaire : abandon"
		error=1
	fi

else
	echo "Le dossier temporaire n'existe pas"
	error=1
fi
}

#####################################
## Définition du type de conteneur ##
#####################################


##fonction

analyse_conteneur () {


#Définition de la variable sur la sortie de la commande "file"
file_type="`file -b "$original"`"

mpeg="MPEG"
avi="AVI"
mp4="MP4"
mkv="MKV"
flv="FLV"
ogm="OGM"
ogg="Ogg/Theora"

###boucle de détection

case "$file_type" in

#Video MPEG
	*"MPEG sequence"*)
		conteneur="$mpeg"
		;;		

#Video AVI
	*"AVI"*)
		conteneur="$avi"
		;;		
#Video MP4
	*"MPEG v4 system"*)
		conteneur="$mp4"
		;;		

#Video MKV
	*"Matroska data"*)
		conteneur="$mkv"
		;;		

#Video FLV
	*"Macromedia Flash Video"*)
		conteneur="$flv"
		;;		

#Video OGM
	*"OGM video"*)
		conteneur="$ogm"
		;;	
#Video OGG Theora
	*"Theora "*)
		conteneur="$ogg"
		;;
		
esac

#Debug
#echo "$conteneur"

#Affichage du conteneur
case "$conteneur" in
	"$mpeg"|"$avi"|"$mp4"|"$mkv"|"$flv"|"$ogm"|"$ogg")
		echo "Le conteneur de cette vidéo est au format $conteneur"
		;;
#Fichiers non pris en charge	
	*)
		echo "Le fichier n'est pas pris en charge par le script"
		error=1
		;;

esac
}

#############################
## Demultiplexage des flux ##
#############################


### Format MKV ###


#Fonction analyse de flux

flux_mkv () {

#Script d'analyse de flux de fichier mkv


###Définition des variables

#variable de la sortie de mkvinfo et mkvmerge -i
var_mkvinfo="`mkvinfo "$original"`"
var_mkvmerge="`mkvmerge -i "$original"`"

#Numéros
un=1
deux=2
trois=3

#États de pistes
audio="audio"
video="vidéo"
subtitles="Sous-titres"

#Variable d'erreur
error=0

#vérification du nombre de pistes

number_track="`echo "$var_mkvmerge" | grep -c '^Track'`"


####Analyse du contenu des flux

#MKV à une piste
if test "$number_track" = "$un"
	then
		case "$var_mkvinfo" in
			*"Track type: video"*)
				track_un="$video"
			;;
			
			*"Track type: audio"*)
				track_un="$audio"
			;;

			*"Track type: subtitles"*)
				track_un="$subtitles"
			;;
		esac

#MKV à deux pistes
elif test "$number_track" = "$deux"
	then
		case "$var_mkvinfo" in
		#Dans le cas où la seconde piste est une piste vidéo
			*"Track number: 2"*"Track type: video"*)
				track_deux="$video"
					#Imbrication d'une troisième boucle pour tester la première piste
						case "$var_mkvinfo" in
							*"Track type: video"*"Track type: video"*)
								track_un="$video"
							;;
							*"Track type: audio"*"Track type: video"*)
								track_un="$audio"
							;;
							*"Track type: subtitles"*"Track type: video"*)
								track_un="$subtitles"
							;;
						esac
					#Fin de la boucle
							
			;;

		#Dans le cas où la seconde piste est une piste audio
			*"Track number: 2"*"Track type: audio"*)
				track_deux="$audio"
					#Imbrication d'une troisième boucle pour tester la première piste
						case "$var_mkvinfo" in
							*"Track type: video"*"Track type: audio"*)
								track_un="$video"
							;;
							*"Track type: audio"*"Track type: audio"*)
								track_un="$audio"
							;;
							*"Track type: subtitles"*"Track type: audio"*)
								track_un="$subtitles"
							;;
						esac
					#Fin de la boucle
			;;

		#Dans le cas où la seconde piste est une piste de sous-titres
			*"Track number: 2"*"Track type: subtitles"*)
				track_deux="$subtitles"
					#Imbrication d'une troisième boucle pour tester la première piste
						case "$var_mkvinfo" in
							*"Track type: video"*"Track type: subtitles"*)
								track_un="$video"
							;;
							*"Track type: audio"*"Track type: subtitles"*)
								track_un="$audio"
							;;
							*"Track type: subtitles"*"Track type: subtitles"*)
								track_un="$subtitles"
							;;
						esac
					#Fin de la boucle
			;;
		esac

#MKV à trois pistes
elif test "$number_track" = "$trois"
	then
		case "$var_mkvinfo" in
		#Dans le cas où la troisième piste est une piste vidéo
			*"Track number: 3"*"Track type: video"*)
				track_trois="$video"
					#Imbrication d'une troisième boucle pour tester les deux premières pistes
						case "$var_mkvinfo" in
							#Piste 2 est de la vidéo
							*"Track type: video"*"Track type: video"*"Track type: video"*)
								track_un="$video"
								track_deux="$video"
							;;
							*"Track type: audio"*"Track type: video"*"Track type: video"*)
								track_un="$audio"
								track_deux="$video"
							;;
							*"Track type: subtitles"*"Track type: video"*"Track type: video"*)
								track_un="$subtitles"
								track_deux="$video"
							;;
							#Piste 2 est de l'audio
							*"Track type: video"*"Track type: audio"*"Track type: video"*)
								track_un="$video"
								track_deux="$audio"
							;;
							*"Track type: audio"*"Track type: audio"*"Track type: video"*)
								track_un="$audio"
								track_deux="$audio"
							;;
							*"Track type: subtitles"*"Track type: audio"*"Track type: video"*)
								track_un="$subtitles"
								track_deux="$audio"
							;;
							#Piste 2 sont des sous-titres
							*"Track type: video"*"Track type: subtitles"*"Track type: video"*)
								track_un="$video"
								track_deux="$subtitles"
							;;
							*"Track type: audio"*"Track type: subtitles"*"Track type: video"*)
								track_un="$audio"
								track_deux="$subtitles"
							;;
							*"Track type: subtitles"*"Track type: subtitles"*"Track type: video"*)
								track_un="$subtitles"
								track_deux="$subtitles"
							;;
						esac
					#Fin de la boucle
				;;
		#Dans le cas où la troisième piste est une piste audio
			*"Track number: 3"*"Track type: audio"*)
				track_trois="$audio"
					#Imbrication d'une troisième boucle pour tester les deux premières pistes
						case "$var_mkvinfo" in
							#Piste 2 est de la vidéo
							*"Track type: video"*"Track type: video"*"Track type: audio"*)
								track_un="$video"
								track_deux="$video"
							;;
							*"Track type: audio"*"Track type: video"*"Track type: audio"*)
								track_un="$audio"
								track_deux="$video"
							;;
							*"Track type: subtitles"*"Track type: video"*"Track type: audio"*)
								track_un="$subtitles"
								track_deux="$video"
							;;
							#Piste 2 est de l'audio
							*"Track type: video"*"Track type: audio"*"Track type: audio"*)
								track_un="$video"
								track_deux="$audio"
							;;
							*"Track type: audio"*"Track type: audio"*"Track type: audio"*)
								track_un="$audio"
								track_deux="$audio"
							;;
							*"Track type: subtitles"*"Track type: audio"*"Track type: audio"*)
								track_un="$subtitles"
								track_deux="$audio"
							;;
							#Piste 2 sont des sous-titres
							*"Track type: video"*"Track type: subtitles"*"Track type: audio"*)
								track_un="$video"
								track_deux="$subtitles"
							;;
							*"Track type: audio"*"Track type: subtitles"*"Track type: audio"*)
								track_un="$audio"
								track_deux="$subtitles"
							;;
							*"Track type: subtitles"*"Track type: subtitles"*"Track type: audio"*)
								track_un="$subtitles"
								track_deux="$subtitles"
							;;
						esac
					#Fin de la boucle
				;;
		#Dans le cas où la troisième piste est une piste de sous-titres
			*"Track number: 3"*"Track type: subtitles"*)
				track_trois="$subtitles"
					#Imbrication d'une troisième boucle pour tester les deux premières pistes
						case "$var_mkvinfo" in
							#Piste 2 est de la vidéo
							*"Track type: video"*"Track type: video"*"Track type: subtitles"*)
								track_un="$video"
								track_deux="$video"
							;;
							*"Track type: audio"*"Track type: video"*"Track type: subtitles"*)
								track_un="$audio"
								track_deux="$video"
							;;
							*"Track type: subtitles"*"Track type: video"*"Track type: subtitles"*)
								track_un="$subtitles"
								track_deux="$video"
							;;
							#Piste 2 est de l'audio
							*"Track type: video"*"Track type: audio"*"Track type: subtitles"*)
								track_un="$video"
								track_deux="$audio"
							;;
							*"Track type: audio"*"Track type: audio"*"Track type: subtitles"*)
								track_un="$audio"
								track_deux="$audio"
							;;
							*"Track type: subtitles"*"Track type: audio"*"Track type: subtitles"*)
								track_un="$subtitles"
								track_deux="$audio"
							;;
							#Piste 2 sont des sous-titres
							*"Track type: video"*"Track type: subtitles"*"Track type: subtitles"*)
								track_un="$video"
								track_deux="$subtitles"
							;;
							*"Track type: audio"*"Track type: subtitles"*"Track type: subtitles"*)
								track_un="$audio"
								track_deux="$subtitles"
							;;
							*"Track type: subtitles"*"Track type: subtitles"*"Track type: subtitles"*)
								track_un="$subtitles"
								track_deux="$subtitles"
							;;
						esac
					#Fin de la boucle
			;;

		esac
#Cas d'erreur
else
		echo "Le fichier MKV ne peut pas être traité par ce script"
		error=1

fi



#Affichage du détail de l'analyse

if test "$number_track" = "$un"
	then
		echo "Le fichier MKV contient une seule piste"
		echo "Piste 1 : $track_un"
			#Vérification de la présence de vidéo
			case "$video" in
				"$track_un")
				;;
				*)
					echo "Le fichier ne contient pas de video, il ne peut pas être traité par le script"
					error=1
				;;
			esac

elif test "$number_track" = "$deux"
	then
		echo "Le fichier MKV contient deux pistes"
		echo "Piste 1 : $track_un"
		echo "Piste 2 : $track_deux"
			#Vérification de la présence de vidéo
			case "$video" in
				"$track_un"|"$track_deux")
				;;
				*)
					echo "Le fichier ne contient pas de video, il ne peut pas être traité par le script"
					error=1
				;;
			esac
elif test "$number_track" = "$trois"
	then
		echo "Le fichier MKV contient trois pistes"
		echo "Piste 1 : $track_un"
		echo "Piste 2 : $track_deux"
		echo "Piste 3 : $track_trois"
			#Vérification de la présence de vidéo
			case "$video" in
				"$track_un"|"$track_deux"|"$track_trois")
					#Vérification de la présence de sous-titres
					case "$subtitles" in
						"$track_un"|"$track_deux"|"$track_trois")
						;;
						*)
							echo "Le fichier ne contient pas de sous-titres, retirez la piste superflux manuellement du fichier et relancer le script"
							error=1
							;;
					esac
				;;
				*)
					echo "Le fichier ne contient pas de video, il ne peut pas être traité par le script"
					error=1
				;;
			esac

else
		echo "Le fichier MKV contient plus de 3 pistes ou n'est pas valide, il ne peut pas être traité par ce script"
		error=1
fi

#Ça a marché du premier coup ^o^
#Je sais, ce script est moche, mais il marche !

}

#Fonction demultiplexage des flux

demult_mkv () {


#Variables

ext_1="1:"$track_un""
ext_2="2:"$track_deux""

#Pour la piste 3, vérifie que la variable est non nul
if [ -n "$track_trois" ]
	then 
		ext_3="3:"$track_trois""
fi


#debug
#
#echo "ext_1 = "$ext_1""
#echo "ext_2 = "$ext_2""
#echo "ext_3 = "$ext_3""



#Désactivation de la piste vidéo pour éviter les erreurs
case "$video" in
	"$track_un")
		ext_1= #efface la variable ext_1
	;;
	"$track_deux")
		ext_2= #efface la variable ext_2
	;;
	"$track_trois")
		ext_3= #efface la variable ext_3
	;;
esac

#Demultiplexage

if [ "$error" -eq "0" ]
	then
		echo "Lancement du demultiplexage des pistes"

		#Cas d'un fichier à 2 ou 3 pistes
		if [ "$number_track" -ge "$deux" ]
			then 	
				echo "Demultiplexage des pistes du fichier"
#Debug				echo "Debug : mkvextract tracks "$original" $ext_1 $ext_2 $ext_3"
				if mkvextract tracks "$original" $ext_1 $ext_2 $ext_3
					then
						echo "Demultiplexage effectué avec succès"
						
					else
						echo "Il y a semble-t-il eu un problème lors du demultiplexage du fichier MKV"
						error=1
				fi

		#Cas d'un fichier d'une seule piste
		elif [ "$number_track" -eq "$un" ]
			then
				echo "Le fichier ne contient qu'une seule piste vidéo, il n'est pas nécessaire de le demultiplexer"
		fi
else
	echo "Une erreur s'est produite, il n'est pas possible d'effectuer le demultiplexage du fichier MKV (erreur "$error")"
fi					
}




########################
## Encodage piste son ##
########################


# Decompression et convertion de la piste audio #
###################################


audio_conv () {

#Variables

orig_audio="$audio"
wav_audio=""$audio"_wav"
aac_audio=""$audio"_aac"

#Test du format de fichier avec file
audio_format="`file -b "$orig_audio"`"


#Convertion
case "$audio_format" in

#Si le fichier est déjà au format aac
	*AAC*)
		echo "Le format de la piste son est au format AAC, il ne sera pas réencodé"
		#Renommage du fichier
		if mv "$orig_audio" "$aac_audio"
			then
				echo "Le fichier \""$orig_audio"\" a été renommé \""$aac_audio"\""
		else
			echo "Une erreur s'est produite lors du renommage du fichier"
			error=1
		fi
		;;

#S'il s'agit d'un autre format
	*)
		echo "Le fichier va être décompressé vers un format wav"
		#Utilisation de mplayer pour la convertion du fichier vers wav
		if mplayer "$orig_audio" -ao pcm:file="$wav_audio"
			then
				echo "Le fichier a été convertie au format wav"
				echo "Convertion au format aac..."
					#Convertion du fichier vers le format aac avec faac
					if faac -o "$aac_audio" "$wav_audio"
						then
							echo "le fichier a été convertie avec succès"
						else
							echo "Une erreur s'est produite lors de la conversion du fichier vers le format aac"
							error=1
					fi
				else
					echo "Une erreur s'est produite lors de la conversion du fichier vers le format wav"
					error=1
		fi
		;;
esac

}

##########################
## Encodage piste vidéo ##
##########################





#################################
## Multiplexage du fichier MKV ##
#################################



#########################
## Execution du script ##
#########################

echo "Script de convertion de fichier vidéo pour appareils mobiles."
echo "Licence GPL 3.0"


#Execution de la fonction test_dir
if testing_dir
	then
		#Si absence d'erreur, execute la fonction analyse_conteneur
		if [ "$error" -eq "0" ]
			then
				echo "Démarrage du processus d'analyse de conteneur"
				analyse_conteneur
		fi

fi

#Séquence de démultiplexage de fichier
if [ "$error" -eq "0" ]
	then
		case "$conteneur" in
			#Pour les fichiers MKV
			"$mkv")
				#Execution de la fonction flux_mkv
				flux_mkv
				if [ "$error" -eq "0" ]
					then 
						#Si absence d'erreur, execution de tmp_create
						tmp_create
						if [ "$error" -eq "0" ]
							then
								#Si absence d'erreur, execution de demult_mkv
								demult_mkv
								if [ "$error" -eq "0" ]
									then
										#Si absence d'erreur, execution de audio_conv
										audio_conv
								else
									echo "Une erreur s'est produite, abandon (erreur $error)"
								fi
						else
							echo "Une erreur s'est produite, abandon (erreur $error)"
						fi
					else
						echo "Une erreur s'est produite, abandon (erreur $error)"
				fi
			;;
			#Pour les autres types de fichiers
			"$mpeg"|"$avi"|"$mp4"|"$ogm"|"$ogg")
				tmp_create_mkv
				if [ "$error" -eq "0" ]
					then 
						#Si absence d'erreur, execution de tmp_create
						flux_mkv
						if [ "$error" -eq "0" ]
							then
								#Si absence d'erreur, execution de demult_mkv
								demult_mkv
								if [ "$error" -eq "0" ]
									then
										#Si absence d'erreur, execution de audio_conv
										audio_conv
								else
									echo "Une erreur s'est produite, abandon (erreur $error)"
								fi
						else
							echo "Une erreur s'est produite, abandon (erreur $error)"
						fi
					else
						echo "Une erreur s'est produite, abandon (erreur $error)"
				fi
			;;
			*)
				echo "Le conteneur n'est pas pris en charge par le script"
				error=1
			;;
		esac
else
	echo "Une erreur s'est produite, abandon (erreur $error)"
fi

Il est d'ors et déjà fonctionnel pour l'analyse et le démultiplexage de fichier mkv. Il y a encore pas mal d'optimisations à faire et ça reste néanmoins du code de débutant, mais je pense aller dans la bonne direction pour la suite.

Maj 7/08/08

Pour ceux qui serait intéressé par l'avancement du code, je fais une mise à jour.

Une fonction permettant de rendre compatible le script avec d'autres formats que le MKV a été ajouté. J'ai eu l'idée de muxer les autres fichier vidéo dans un fichier mkv, mkvmerge permet de le faire très facilement. J'ai également ajouté la fonction qui permet de convertir la piste audio.

Il ne manque plus que l'encodage vidéo, le multiplexage mkv, ainsi que la possibilité de faire fonctionner le script en mode deamon, et ça sera terminé.

Dernière modification par Goldy (Le 07/08/2008, à 17:22)

Hors ligne

#12 Le 09/08/2008, à 23:43

Goldy

Re : [Résolu] [Shell] Extraire une chaine de caractère d'une variable

Je lutte toujours un peu avec l'extraction de chaines de caractères. J'ai maintenant besoin de définir la résolution de la vidéo à encoder, et j'ai besoin d'extraire l'information du résultat de la commande mkvinfo.

Voilà ce que me donne la commande mkvinfo (sans retour de charriot):

mkv_info_copy = + EBML head |+ Doc type: matroska |+ Doc type version: 1 |+ Doc type read version: 1 + Segment, size 57248150 |+ Seek head (subentries will be skipped) |+ EbmlVoid (size: 4027) |+ Segment information | + Timecode scale: 1000000 | + Muxing application: libebml v0.7.7 + libmatroska v0.8.1 | + Writing application: mkvmerge v2.2.0 ('Turn It On Again') built on Mar 4 2008 04:56:48 | + Duration: 213.079s (00:03:33.079000000) | + Date: Sat Aug 9 00:23:20 2008 UTC | + Segment UID: 0xb0 0x12 0xe7 0xd9 0xaf 0xc4 0xce 0xa0 0x9a 0xb6 0xdf 0x3b 0xa5 0x23 0x80 0xcc |+ Segment tracks | + A track | + Track number: 1 | + Track UID: 3607199436 | + Track type: video | + Enabled: 1 | + Default flag: 1 | + Forced flag: 0 | + Lacing flag: 0 | + MinCache: 1 | + Timecode scale: 1.000000 | + Max BlockAddition ID: 0 | + Codec ID: V_MS/VFW/FOURCC | + Codec decode all: 1 | + CodecPrivate, length 40 (FourCC: DX50, 0x30355844) | + Default duration: 33.367ms (29.970 fps for a video track) | + Language: und | + Video track | + Pixel width: 640 | + Pixel height: 480 | + Interlaced: 0 | + Display width: 640 | + Display height: 480 | + A track | + Track number: 2 | + Track UID: 1985060098 | + Track type: audio | + Enabled: 1 | + Default flag: 1 | + Forced flag: 0 | + Lacing flag: 1 | + MinCache: 0 | + Timecode scale: 1.000000 | + Max BlockAddition ID: 0 | + Codec ID: A_MPEG/L3 | + Codec decode all: 1 | + Default duration: 24.000ms (41.667 fps for a video track) | + Language: und | + Audio track | + Sampling frequency: 48000.000000 | + Channels: 2 |+ EbmlVoid (size: 1024) |+ Cluster

Donc il faut que j'arrive à extraire de ça

Display width: 640

et

Display height: 480

J'ai beau lire le Guide avancé d'écriture des scripts Bash, la commande qui pouvait m'aider (expr match) ne semble pas capable de fonctionner avec autre chose que des [A-Z] [0-9], etc etc. Je ne sais pas comment faire, grep ne prends pas en charge les jokers, donc impossible d'extraire les chiffres variables.

Décidément, l'extraction de chaine de caractère est vraiment ce qui me pose le plus de problème dans la création de ce script.

Hors ligne

#13 Le 10/08/2008, à 01:42

Link31

Re : [Résolu] [Shell] Extraire une chaine de caractère d'une variable

mkvinfo | sed -e 's/| *+ */\n/g' | grep "Display" # "Display width" ou "Display height"

Dernière modification par Link31 (Le 10/08/2008, à 01:43)

Hors ligne

#14 Le 10/08/2008, à 15:16

Goldy

Re : [Résolu] [Shell] Extraire une chaine de caractère d'une variable

Link31 a écrit :
mkvinfo | sed -e 's/| *+ */\n/g' | grep "Display" # "Display width" ou "Display height"

Merci Link31.

Je connaissais pas sed, et ça m'a l'air compliqué ce système de script. Je viens de trouver le chapitre qui en parle dans le guide, je vais potasser un peu pour comprendre la construction. Le script fonctionne correctement en tout cas.

Hors ligne