class MusiqueSon_normalize(Base): # ----------------------------------- # Cadre accueillant les widgets de : # Musique-Son >> Encodage # ----------------------------------- def __init__(self, parent): # ------------------------------- # Parametres généraux du widget # ------------------------------- self.config=EkdConfig self.parent = parent #=== Identifiant de la classe ===# self.idSection = "son_normaliser_convertir_musique_ou_son" super(MusiqueSon_normalize, self).__init__(None, None, None, 'vbox') # Base module de animation self.setTitle(_(u"Normaliser et convertir un fichier audio")) self.printSection() #------------------------------------------------------------------------ # TabWidget pour les réglages et pour l'écoute du résultat #------------------------------------------------------------------------ extFormat=[] for fmt in self.parent.soxSuppFormat : extFormat.append("*."+fmt) # Widget standard de sélection de fichier audio dans le tab standard self.selectionAudioFile = SelectWidget(extensions = extFormat, mode="texte", audio = True) # Onglets self.tab.insertTab(0,self.selectionAudioFile, _(u'Son(s) source')) self.connect(self.selectionAudioFile,SIGNAL("fileSelected"),self.synchroFiles) self.connect(self.selectionAudioFile, SIGNAL("pictureChanged(int)"), self.synchroFiles) ## --------------------------------------------------------------------- # Variables pour la fonction tampon ## --------------------------------------------------------------------- self.typeEntree = "audio" # Défini le type de fichier source. self.typeSortie = "audio" # Défini le type de fichier de sortie. self.sourceEntrees = self.selectionAudioFile # Fait le lien avec le sélecteur de fichier source. # ------------------------------------------------------------------- # Sélection et affichage des fichiers à joindre : "Fichiers audio source" # ------------------------------------------------------------------- reglage = QWidget() regVLayout = QVBoxLayout(reglage) self.selectionFile = choixSonSortieWidget(self.parent.soxSuppFormat, parent=self) regVLayout.addWidget(self.selectionFile) niveau = QGroupBox(_(u"Choix du niveau")) self.choix1 = QRadioButton(_(u"- 3 dB")) self.choix2 = QRadioButton(_(u"- 6 dB")) self.choix3 = QRadioButton(_(u"- 9 dB")) self.choix1.setChecked(True) nivLayout = QHBoxLayout() nivLayout.addWidget(self.choix1) nivLayout.addWidget(self.choix2) nivLayout.addWidget(self.choix3) niveau.setLayout(nivLayout) regVLayout.addWidget(niveau) mode = QGroupBox(_(u"Choix du mode de normalisation")) self.choixm1 = QRadioButton(_(u"Standard")) self.choixm2 = QRadioButton(_(u"Individuel")) self.choixm3 = QRadioButton(_(u"Balancé")) self.choixm1.setChecked(True) modeLayout = QHBoxLayout() modeLayout.addWidget(self.choixm1) modeLayout.addWidget(self.choixm2) modeLayout.addWidget(self.choixm3) mode.setLayout(modeLayout) regVLayout.addWidget(mode) regVLayout.addStretch() self.tab.addTab(reglage,_(u"Réglage")) #------------------------------------------------------------------------ # Ecoute du résultat #------------------------------------------------------------------------ #=== Widgets mplayer ===# widget = QWidget() vboxMplayer = QVBoxLayout(widget) vboxMplayer.addStretch() hbox = QHBoxLayout() vboxMplayer.addLayout(hbox) hbox.addStretch() self.mplayer=Mplayer(taille=(300,270), facteurLimitant=Mplayer.LARGEUR, choixWidget=(Mplayer.PAS_PRECEDENT_SUIVANT,Mplayer.CURSEUR_A_PART)) self.mplayer.setAudio(True) hbox.addWidget(self.mplayer) hbox.addStretch() vboxMplayer.addStretch() self.mplayer.setEnabled(False) self.tab.addTab(widget, _(u"Son créé")) ### pour les infos supplémentaires self.addLog() # ------------------------------------------------------------------- # widgets du bas : ligne + boutons Aide et Appliquer # ------------------------------------------------------------------- def synchroFiles(self): if len(self.selectionAudioFile.getFiles()) > 0 : self.boutApp.setEnabled(True) else : self.boutApp.setEnabled(False) def endProcess(self, sortie) : self.mplayer.setEnabled(True) self.mplayer.listeVideos = [sortie] self.tab.setCurrentIndex(1) self.infoLog(None, None, self.selectionAudioFile.getFile(), sortie) def afficherAide(self): """ Boîte de dialogue de l'aide """ self.aide = EkdAide(550,400,self) self.aide.setText(_(u"<p><b>Ici vous pouvez normaliser des fichiers audio, c'est à dire ajuster leur volume sonore. Voici une définition selon Wikipédia de la normalisation audio:<br>http://fr.wikipedia.org/wiki/Normalisation_audio</b></p><p>Dans l'onglet <b>Son(s) source</b> cliquez sur le bouton <b>Ajouter</b>, une boîte de dialogue apparaît, sur la partie gauche sélectionnez le répertoire (au besoin dépliez les sous-répertoires), allez chercher la/les fichiers(s) audio. Si vous voulez sélectionner plusieurs fichiers audio d'un coup, maintenez la touche <b>CTRL</b> (ou <b>SHIFT</b>) du clavier enfoncée (tout en sélectionnant vos fichiers audio), cliquez sur <b>Ajouter</b>.</p><p>Vous pouvez dès lors sélectionner un fichier audio dans la liste et le lire (par le bouton juste à la droite de cette liste). De même si vous le désirez, vous pouvez obtenir des informations complètes sur le fichier audio sélectionné, et ce par le bouton <b>Infos</b> (en bas).</p><p>Dans l'onglet <b>Réglages</b> sélectionnez le <b>Format du fichier de sortie</b>, et s'il le faut <b>Réglage expert</b> et faites éventuellement le réglage de la <b>Qualité d'encodage</b>, puis réglez le <b>Choix du niveau</b> et le <b>Choix du mode de normalisation</b>.</p><p>Une fois tout ceci fait, cliquez sur le bouton <b>Appliquer</b>, sélectionnez le répertoire de sauvegarde, indiquez votre <b>Nom de fichier</b>, cliquez sur le bouton <b>Enregistrer</b> et attendez le temps de la conversion. A la fin du traitement cliquez sur le bouton <b>Fermer</b> de la fenêtre <b>Affichage de la progression</b>.</p><p>Dans l'onglet <b>Son créé</b> vous pouvez lire le résultat.</p><p>L'onglet <b>Infos</b> vous permet de voir les fichiers audio chargés (avec leurs chemins exacts) avant et après conversion.</p>")) self.aide.show() def appliquer(self): """ appelle la boite de dialogue de sélection de fichier à sauver """ suffixSortie = u"."+self.selectionFile.getFileExt() saveDialog = EkdSaveDialog(self, mode="audio", suffix=suffixSortie, title=_(u"Sauver")) cheminAudioSorti = saveDialog.getFile() if not cheminAudioSorti: return # récupération du chemin des fichiers audio source cheminAudioSource=self.selectionAudioFile.getFile() # suffix du fichier actif suffix=os.path.splitext(cheminAudioSource)[1] if suffix == u".mp3" or suffix == u".MP3" : chemin = u"-t mp3 \""+cheminAudioSource+u"\"" elif suffix == u".ogg" or suffix == u".OGG" : chemin = u"-t ogg \""+cheminAudioSource+u"\"" elif suffix == u".mp2" or suffix == u".MP2" : chemin = u"-t mp2 \""+cheminAudioSource+u"\"" elif suffix == u".flac" or suffix == u".FLAC" : chemin = u"-t flac \""+cheminAudioSource+u"\"" else : chemin = u"\""+cheminAudioSource+u"\"" # Définition des options if self.choix1.isChecked() : db = " -3 " if self.choix2.isChecked() : db = " -6 " if self.choix3.isChecked() : db = " -9 " if self.choixm1.isChecked() : mde = "" if self.choixm2.isChecked() : mde = "-i" if self.choixm3.isChecked() : mde = "-b" option = "norm "+mde+db if self.selectionFile.reglageExp.getExpertState() : regExp = self.selectionFile.reglageExp.getC() else : regExp = u"" # Encodage self.process = SoxProcess(chemin, cheminAudioSorti, 1, u"", u""+regExp, option, self.parent) self.process.setSignal(u"Input",u"In:") self.process.show() self.process.run() self.connect(self.process,SIGNAL("endProcess"),self.endProcess) def load(self) : self.selectionAudioFile.loadFileLocation(self.idSection) self.selectionFile.reglageExp.loadConfig(self.idSection) self.choix1.setChecked(int(EkdConfig.get(self.idSection, 'choix1'))) self.choix2.setChecked(int(EkdConfig.get(self.idSection, 'choix2'))) self.choix3.setChecked(int(EkdConfig.get(self.idSection, 'choix3'))) self.choixm1.setChecked(int(EkdConfig.get(self.idSection, 'choixm1'))) self.choixm2.setChecked(int(EkdConfig.get(self.idSection, 'choixm2'))) self.choixm3.setChecked(int(EkdConfig.get(self.idSection, 'choixm3'))) def save(self) : self.selectionAudioFile.saveFileLocation(self.idSection) self.selectionFile.reglageExp.saveConfig(self.idSection) EkdConfig.set(self.idSection, u'choix1', unicode(int(self.choix1.isChecked()))) EkdConfig.set(self.idSection, u'choix2', unicode(int(self.choix2.isChecked()))) EkdConfig.set(self.idSection, u'choix3', unicode(int(self.choix3.isChecked()))) EkdConfig.set(self.idSection, u'choixm1', unicode(int(self.choixm1.isChecked()))) EkdConfig.set(self.idSection, u'choixm2', unicode(int(self.choixm2.isChecked()))) EkdConfig.set(self.idSection, u'choixm3', unicode(int(self.choixm3.isChecked())))
class MusiqueSon_decoupe(Animation_MontagVideoDecoupUneVideo): """Class pour la découpe de fichier son. Class dérivée de celle permettant de découper une vidéo dans le module animation""" # ----------------------------------- # Cadre accueillant les widgets de : # Musique-Son >> Encodage # ----------------------------------- def __init__(self, parent): super(MusiqueSon_decoupe, self).__init__(parent) # Vérification des possibilités de Sox pour l'encodage self.setTitle(_(u"Découpe de musiques et de sons")) self.parent = parent # ------------------------------- # Divergeances par rapport à la class Musique Son_decoupe # ------------------------------- self.idSection = "son_decoupe_musiques_et_sons" # ------------------------------------------------------------------- # Boîte de groupe : "Fichier audio source" # ------------------------------------------------------------------- self.radioSource.setText(_(u"Fichier son source")) self.radioConvert.setText(_(u"Son final")) self.mplayer.cibleVideo.hide() self.mplayer.conf.hide() self.mplayer.setToolTip(_(u"La lecture du fichier audio est nécessaire pour achever la sélection d'une zone de la piste audio")) self.boutExtractionSon.hide() ### Option de fade in / fade out sur le son decoupe hlbox = QHBoxLayout() self.fadeIn = QCheckBox(_(u"Fade in")) self.fadeIn.setDisabled(True) self.fadeInTime = QDoubleSpinBox() self.fadeInTime.setDecimals(3) self.fadeInTime.setRange(0.500, 5.000) self.fadeInTime.setValue(1.000) self.fadeInTime.setDisabled(True) self.fadeOut = QCheckBox(_(u"Fade out")) self.fadeOut.setDisabled(True) self.fadeOutTime = QDoubleSpinBox() self.fadeOutTime.setDecimals(3) self.fadeOutTime.setRange(0.500, 5.000) self.fadeOutTime.setValue(1.000) self.fadeOutTime.setDisabled(True) self.boutMarqFinSelect_max.setToolTip(_(u"Marquer la fin de la sélection au temps maximum (t=\"la durée de la piste audio\")")) hlbox.addStretch(100) hlbox.addWidget(self.fadeIn) hlbox.addWidget(self.fadeInTime) hlbox.addStretch(20) hlbox.addWidget(self.fadeOut) hlbox.addWidget(self.fadeOutTime) hlbox.addStretch(100) self.layoutReglage.insertLayout(3,hlbox) ### Pour n'activer les QDoubleSpinBox que lorsque les QCheckBox correspondantes ### sont activees. self.connect(self.fadeIn, SIGNAL("stateChanged(int)"), self.fadeInTime.setEnabled) self.connect(self.fadeOut, SIGNAL("stateChanged(int)"), self.fadeOutTime.setEnabled) ### Zone de selection du format de sortie de fichier hbox = QHBoxLayout() # Utilisation du widget choixSonSortieWidget self.choixFormatAudio = choixSonSortieWidget(self.parent.soxSuppFormat, parent=self) extFormat=[] for fmt in self.parent.soxSuppFormat : extFormat.append("*."+fmt) hbox.addWidget(self.choixFormatAudio) self.layoutReglage.insertLayout(0,hbox) #------------------------------------------------------------------- # Modification de la nouvelle interface d'ajout des videos pour l'adapter aux fichiers son self.afficheurVideoSource=SelectWidget(extensions = extFormat, mode="texte", audio = True) # Onglets self.tab.removeTab(0) self.indexVideoSource = self.tab.insertTab(0,self.afficheurVideoSource, _(u'Son(s) source')) self.connect(self.afficheurVideoSource,SIGNAL("fileSelected"),self.getFile) self.connect(self.afficheurVideoSource, SIGNAL("pictureChanged(int)"), self.getFile) #-------------------------------------------------------------------- self.tab.setCurrentIndex(0) ## --------------------------------------------------------------------- # Variables pour la fonction tampon ## --------------------------------------------------------------------- self.typeEntree = "audio" # Défini le type de fichier source. self.typeSortie = "audio" # Défini le type de fichier de sortie. self.sourceEntrees = self.afficheurVideoSource # Fait le lien avec le sélecteur de fichier source. def getFile(self): ''' # Modifié par rapport à la fonction getFile de la class decoupe_video On utilise la nouvelle interface de récupération des fichiers sources slectionnés ''' self.chemin = unicode(self.afficheurVideoSource.getFile()) if not self.chemin: ### Desactive les options si pas de fichier d'entree introduit. self.fadeIn.setDisabled(True) self.fadeInTime.setDisabled(True) self.fadeOut.setDisabled(True) self.fadeOutTime.setDisabled(True) return # Affichage du chemin + nom de fichier dans la ligne d'édition self.mplayer.setEnabled(True) self.mplayer.listeVideos = [self.chemin] self.radioSource.setChecked(True) self.radioSource.setEnabled(True) self.radioConvert.setChecked(False) self.radioApercu.setChecked(False) self.fadeIn.setEnabled(True) self.fadeOut.setEnabled(True) self.miseAZeroSelect() # les boutons de marquage apparaissent self.frameMarque.setEnabled(True) def afficherAide(self): """ Boîte de dialogue de l'aide """ self.aide = EkdAide(550,280,self) self.aide.setText(_(u"""<p><b>Vous pouvez ici découper un fichier audio et ainsi en garder uniquement la partie qui vous intéresse.</b></p><p><font color='green'>Ce cadre est assez différent des autres, vous avez tout d'abord la zone d'écoute audio, comprenant les boutons marche, arrêt et le compteur, la glissière de défilement, la zone d'affichage de la découpe (les parties découpées seront affichées en vert), les boutons début/fin de sélection, remise à zéro, à la doite de ce dernier bouton, vous avez trois minuscules boutons contenant +, = et - (ils servent à accélérer ou diminuer la vitesse de lecture du fichier audio), une première case à cocher <b>Fade in</b> (qui peut appliquer un effet de fondu au début de la découpe du son), juste à la droite, le réglage du fondu, une deuxième case à cocher <b>Fade out</b> (qui peut appliquer un effet de fondu à la fin de la découpe du son), le réglage du fondu correspondant, puis les choix d'écoute <b>Fichier son source</b>, <b>aperçu</b> et <b>Son final</b>.</font></p><p><b>Tout ce qui vient de vous être décrit se trouve dans l'onglet Réglages</b>.</p><p>Dans l'onglet <b>Son(s) source</b> cliquez sur le bouton <b>Ajouter</b>, une boîte de dialogue apparaît, sur la partie gauche sélectionnez le répertoire (au besoin dépliez les sous-répertoires), allez chercher la/les fichier(s) audio. Si vous voulez sélectionner plusieurs fichiers audio d'un coup, maintenez la touche <b>CTRL</b> (ou <b>SHIFT</b>) du clavier enfoncée (tout en sélectionnant vos fichiers), cliquez sur <b>Ajouter</b>.</p><p>Vous pouvez dès lors sélectionner un fichier audio dans la liste et l'écouter (par le bouton juste à la droite de cette liste). De même si vous le désirez, vous pouvez obtenir des informations complètes sur le fichier audio sélectionné, et ce par le bouton <b>Infos</b> (en bas).</p><p>Dans l'onglet <b>Réglages</b>, lancez l'écoute du fichier audio (par le bouton avec la flèche orientée vers la droite <b>La lecture du fichier audio est nécessaire ...</b>), pour la vitesse de lecture, profitez des boutons + ou - pour augmenter ou diminuer la vitesse de lecture <b>(plus vous diminuez la vitesse de lecture, plus la découpe pourra se faire de façon précise)</b>, cliquez ensuite sur le bouton <b>Marquer le début de la sélection</b> ou <b>Marquer le début de la sélection au temps minimum (t=0)</b> (pour sélectionner le fichier audio à son tout début), laissez jouer (écoutez la musique ou le son) et cliquez sur le bouton <b>Marquer la fin de la sélection</b> au moment propice (ou <b>Marquer la fin de la sélection au temps maximum t="la durée du fichier audio"</b> pour garder le dit fichier audio jusqu'à la fin).</p><p><font color='blue'>Sachez que vous pouvez revenir aux paramètres par défaut en cliquant sur le bouton <b>Remettre à zéro les paramètres</b> (les deux flèches vertes inversées), vous devrez alors rejouer le fichier audio et recommencer vos différentes sélections.</font></p><p>Cliquez sur le bouton <b>Appliquer</b>, sélectionnez le répertoire de sauvegarde de votre fichier audio, entrez le <b>Nom de Fichier</b> dans le champ de texte réservé à cet effet ... cliquez sur le bouton <b>Enregistrer</b> et attendez le temps de la conversion. A la fin du traitement cliquez sur le bouton <b>Fermer</b> de la fenêtre <b>Affichage de la progression</b>.</p><p>Vous pouvez visionner votre fichier audio (avant la conversion) en sélectionnant <b>Fichier son source</b>, après la conversion <b>Son final</b>.</p><p>L'onglet <b>Infos</b> vous permet de voir les fichiers audio chargés (avec leurs chemins exacts) avant et après conversion.</p>""")) self.aide.show() def tempsToHMSMS(self,sec) : """Fonction de conversion du temps en seconde vers le temps en HH:MM:SS.MSE""" heure = int(sec/3600.0) minute = int((sec-heure*3600.0)/60.0) seconde = int(sec-heure*3600.0-minute*60.0) millisec = int((sec-heure*3600.0-minute*60.0-seconde)*1000.0) return u"%02d:%02d:%02d.%d" % (heure, minute, seconde, millisec) def appliquer(self): """Découpage du fichier son""" # suffix du fichier actif suffix=os.path.splitext(self.chemin)[1] if suffix == u".mp3" or suffix == u".MP3" : chemin = u"-t mp3 \""+self.chemin+u"\"" elif suffix == u".ogg" or suffix == u".OGG" : chemin = u"-t ogg \""+self.chemin+u"\"" elif suffix == u".mp2" or suffix == u".MP2" : chemin = u"-t mp2 \""+self.chemin+u"\"" elif suffix == u".flac" or suffix == u".FLAC" : chemin = u"-t flac \""+self.chemin+u"\"" else : chemin = u"\""+self.chemin+u"\"" suffixSortie = u".%s" % (self.parent.soxSuppFormat[self.choixFormatAudio.formatSound.currentIndex()]) saveDialog = EkdSaveDialog(self, os.path.expanduser(self.repSortieProv()), suffixSortie, _(u"Sauver")) self.fichierSortie = saveDialog.getFile() if not self.fichierSortie: return tempsDebut = self.tempsToHMSMS(self.valeurDebut) dureeSelection = self.tempsToHMSMS(self.valeurFin - self.valeurDebut) if (self.fadeIn.isChecked() and self.fadeIn.isEnabled()) or \ (self.fadeOut.isChecked() and self.fadeOut.isEnabled()): if self.fadeIn.isChecked() and self.fadeIn.isEnabled() : fadeIn = u"00:00:0%f" % (self.fadeInTime.value()) else : fadeIn = u"00:00:00.000" if self.fadeOut.isChecked() and self.fadeOut.isEnabled() : fadeOut = u"00:00:0%f" % (self.fadeOutTime.value()) else : fadeOut = u"00:00:00.000" fadeOption = u"fade %s %s %s" % (fadeIn, dureeSelection, fadeOut) else : fadeOption = u"" ### Pour le debugage print "extension :", suffix, type(suffix) print "début : ", self.valeurDebut print "fin : ", self.valeurFin print "temps début formaté : ", dureeSelection print "durée : ", dureeSelection print "Input file : ", chemin print "Fichier de sortie : ", self.fichierSortie print u"option : trim %s %s" %(tempsDebut, dureeSelection) if self.choixFormatAudio.reglageExp.getExpertState() : optSortie = self.choixFormatAudio.reglageExp.getC() else : optSortie = u"" ### Encodage avec le module soxProcess self.process = SoxProcess(chemin, self.fichierSortie, 1, u"", optSortie, u"trim %s %s %s" %(tempsDebut, dureeSelection, fadeOption)) self.process.setSignal("Input","In:") self.process.show() self.process.run() self.connect(self.process,SIGNAL("endProcess"),self.endProcess) def endProcess(self, sortie) : """Actions à réaliser lors de la fin du processus d'encodage si celui-ci se termine correctement""" self.radioSource.setEnabled(True) self.radioConvert.setEnabled(True) ### Info sur le traitement effectué. self.infoLog(None, None, self.chemin, self.fichierSortie) def load(self) : self.loadFiles() self.choixFormatAudio.reglageExp.loadConfig(self.idSection) def save(self) : self.saveFiles() self.choixFormatAudio.reglageExp.saveConfig(self.idSection)