2009-07-13 14 views
39

Je suis en train de créer un script Python qui:En utilisant Python pour exécuter une commande sur chaque fichier dans un dossier

  1. Regardez dans le dossier «/entrée »
  2. Pour chaque vidéo dans ce dossier , exécutez une commande mencoder (pour les transcoder en quelque chose jouable sur mon téléphone)
  3. Une fois que mencoder a terminé sa course, supprimez la vidéo originale.

Cela ne semble pas trop difficile, mais je sucent python :)

Toutes les idées sur ce que devrait ressembler le script?

Question bonus: Dois-je utiliser

os.system

ou

subprocess.call

?

Subprocess.call semble permettre un script plus lisible, puisque je peux écrire la commande comme ceci:

cmdLine = [ 'mencoder', sourceVideo, '-ovc', « copie », '-oac', 'copie', '-ss', '00: 02: 54' , '-endpos', '00: 00: 54' , '-o', destinationVideo]

EDIT: Ok, ça fonctionne:

import os, subprocess 

bitrate = '100' 
mencoder = 'C:\\Program Files\\_utilitaires\\MPlayer-1.0rc2\\mencoder.exe' 
inputdir = 'C:\\Documents and Settings\\Administrator\\Desktop\\input' 
outputdir = 'C:\\Documents and Settings\\Administrator\\Desktop\\output' 

for fichier in os.listdir(inputdir): 
    print 'fichier :' + fichier 
    sourceVideo = inputdir + '\\' + fichier 
    destinationVideo = outputdir + '\\' + fichier[:-4] + ".mp4" 

    commande = [mencoder, 
       '-of', 
       'lavf', 
       [...] 
       '-mc', 
       '0', 

       sourceVideo, 
       '-o', 
       destinationVideo] 

    subprocess.call(commande) 

os.remove(sourceVideo) 
raw_input('Press Enter to exit') 

J'ai enlevé la commande mencoder, pour plus de clarté et parce que je travaille toujours.

Merci à tous pour votre contribution.

+0

Grr Je vais avoir toujours le même problème que moi dans ma question précédente; "Windows ne peut pas trouver le fichier spécifié". Python et ou Windows n'est pas un fan des espaces dans les noms de fichiers et de dossiers. :( – Manu

+0

Vous aurez besoin de guillemets autour du chemin du fichier s'il y a des espaces – tgray

Répondre

69

Pour trouver tous les noms de fichiers, utiliser os.listdir().

Ensuite, vous bouclez sur les noms de fichiers. Comme ceci:

import os 
for filename in os.listdir('dirname'): 
    callthecommandhere(blablahbla, filename, foo) 

Si vous préférez un sous-processus, utilisez un sous-processus. :-)

+2

Cela vous donnera des noms de sous-répertoire ainsi que des fichiers, et ne sera pas recourbé dans les sous-répertoires. ne sera pas si simple si vous ne voulez pas que ça se passe mal dans les sous-répertoires –

+0

Eh bien, le dossier d'entrée ne devrait contenir que des fichiers vidéo, pas de sous-répertoires – Manu

+3

@Maciej: Il est facile de filtrer sur l'extension. Vous pouvez aussi utiliser '' glob '' glob.glob ('/ tmp/*. py') ' –

22

Utilisez os.walk pour itérer récursivement sur le contenu du répertoire:

import os 

root_dir = '.' 

for directory, subdirectories, files in os.walk(root_dir): 
    for file in files: 
     print os.path.join(directory, file) 

Pas de différence réelle entre os.system et subprocess.call ici - à moins que vous avez à traiter avec des fichiers étrangement nommés (les noms de fichiers y compris les espaces, guillemets et ainsi de suite). Si tel est le cas, subprocess.call est définitivement meilleur, car vous n'avez pas besoin de faire de shell-citant sur les noms de fichiers. os.le système est meilleur lorsque vous devez accepter une commande de shell valide, par ex. reçu de l'utilisateur dans le fichier de configuration.

+0

pense que vous pourriez avoir obtenu l'ordre faux ...... pour root, dir, fichiers dans .... – ghostdog74

+0

Vous avez raison, j'ai juste corrigé le code. Merci. –

+0

C'était exactement ce que je cherchais. Fondamentalement, une version python de "find. -type f" sur la ligne de commande linux. – chrowe

2

AVI-MPG (choisir vos extensions):

files = os.listdir('/input') 
for sourceVideo in files: 
    if sourceVideo[-4:] != ".avi" 
     continue 
    destinationVideo = sourceVideo[:-4] + ".mpg" 
    cmdLine = ['mencoder', sourceVideo, '-ovc', 'copy', '-oac', 'copy', '-ss', 
     '00:02:54', '-endpos', '00:00:54', '-o', destinationVideo] 
    output1 = Popen(cmdLine, stdout=PIPE).communicate()[0] 
    print output1 
    output2 = Popen(['del', sourceVideo], stdout=PIPE).communicate()[0] 
    print output2 
+0

Dans la ligne 5, je pense que vous vouliez dire sourceVideo [: - 4] –

+0

'sourceVideo' contient seulement le nom de base d'un chemin. – SilentGhost

+0

Si mencoder doit s'exécuter dans le répertoire de travail, ajoutez os.chdir ('/ input') – gimel

1

Ou vous pouvez utiliser la fonction os.path.walk, qui fait plus de travail pour vous que juste os.walk:

stupide Exemple:

def walk_func(blah_args, dirname,names): 
    print ' '.join(('In ',dirname,', called with ',blah_args)) 
    for name in names: 
     print 'Walked on ' + name 

if __name__ == '__main__': 
    import os.path 
    directory = './' 
    arguments = '[args go here]' 
    os.path.walk(directory,walk_func,arguments) 
+2

os.path.walk est maintenant obsolète en faveur de os.walk. –

11

Python peut être trop puissant pour cela.

for file in *; do mencoder -some options $file; rm -f $file ; done 
+1

>> Python pourrait être trop gros certainement pas – ghostdog74

+0

J'utilise ce script comme opportunité pour en apprendre davantage sur Python – Manu

+1

"Quand tout ce que vous avez est un marteau, tout ressemble à un clou" est en quelque sorte ce que vise mon commentaire. – Kurt

1

J'ai eu un problème similaire, avec beaucoup d'aide sur le web et ce post, je fait une petite application, mon objectif est VCD et SVCD et je ne supprime pas la source, mais je pense qu'il sera assez facile à adapter à vos propres besoins.

Il peut convertir 1 vidéo et le couper ou peut convertir toutes les vidéos dans un dossier, les renommer et les mettre dans un sous-dossier/VCD

ajouter également une petite interface, l'espoir que quelqu'un d'autre trouver utile!

je mets le code et le fichier ici BTW: http://tequilaphp.wordpress.com/2010/08/27/learning-python-making-a-svcd-gui/

+1

Il y a beaucoup de code dans ce blog qui ne correspond pas à la question.Il pourrait être utile de retirer le code pertinent et de le coller dans la réponse. Aussi, si le blog change ou tombe en panne, alors cette réponse deviendrait sans valeur, alors que si le code était dans la réponse, il resterait toujours une réponse valide. – Nick