2017-10-03 4 views
0

Ok, l'idée est de créer une file d'attente qui peut être modifiée et réorganisée (ceci est fait) et pour chaque fichier exécuter un processus ffmpeg pour le convertir en un autre format.Créer une file de conversion en utilisant ffmpeg et C#

Pour la conversion, utilisez Xabe.FFmpeg et .Net 4.5 en utilisant async et await. La question serait comment exécuter un nombre x de processus en parallèle (exemple 4) de cette file d'attente variable et quand l'un d'eux finit d'exécuter le suivant, en gardant en exécution toujours le même montant en parallèle. Je peux repartir de zéro mais j'ai besoin d'idées pour le faire de la manière la plus simple possible. Le programme lui-même est simple (avec gui) prend un dossier et ses sous-dossiers tous les fichiers vidéo et les files d'attente et commence la conversion, vous pouvez ajouter d'autres dossiers avec plus de fichiers, et les réorganiser, pour convertir le plus grand.

À un moment donné, j'ai trouvé un paquet je pense nuget (ou github) qui a fait exactement ce dont j'avais besoin, mais je n'ai pas pu revenir.

Merci pour votre aide à l'avance.

Excusez l'anglais parce que j'utilise le traducteur de Google pour être plus rapide parce que mon domaine est limité mais suffisant pour comprendre les réponses.


Ok, j'ai trouvé ce que je cherchais appelé ProcessManager est un paquet nupkg. Il a 2 ans de développement mais semble stable. Le seul inconvénient est qu'il ne me permet pas d'organiser la file d'attente de conversion une fois que vous avez ajouté les fichiers, même si je dois essayer quelques idées qui fonctionne peut-être.

var manager = new Manager(4); // Max 4 processes will be started simultaneously 
manager.Start(); 

manager.ProcessErrorDataReceived += (sender, e) => Console.WriteLine(e.Data); 
manager.ProcessOutputDataReceived += (sender, e) => Console.WriteLine(e.Data); 

foreach (var videoFileName in Directory.EnumerateFiles("videos")) 
{ 
    var info = new ProcessInfo(
     "ffprobe.exe", 
     string.Format("-v quiet -print_format json -show_format -show_streams \"{0}\"", videoFileName)); 

    manager.Queue(info); 
} 

Process Manager

+0

Rechercher 'C# max parallelism' pour beaucoup de guides. – Equalsk

+0

Avez-vous essayé d'utiliser Parallel.ForEach? https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-write-a-simple-parallel-foreach-loop – user2526236

+0

Non, car pour utiliser Prallel.ForEach, la file d'attente ne peut pas changer et ce n'est pas le cas. S'il s'agissait de processus rapides, il n'y a pas de problème, je peux attendre quelques minutes, mais des conversions qui durent des heures sans supervision et qui doivent être réorganisées en fonction des besoins de l'une ou de l'autre vidéo. –

Répondre

1

Je pense que vous pouvez utiliser modèle pseudo producteur-consommateur. Créer quelques tâches qui vont procéder à la conversion et utiliser ConcurrentQueue pour les fichiers de banque à convertir. Chaque travailleur doit obtenir le fichier suivant de la file d'attente et le traiter. De cette façon, vous pouvez réorganiser la file d'attente pendant que les travailleurs travaillent. Vous devez désactiver le multithreading dans ffmpeg (IConversionUseMultiThread (false)).

Certains code:

 ConcurrentQueue<string> filesToConvert = new ConcurrentQueue<string>(); 
     foreach(string file in Directory.GetFiles("C:", "*.mkv")) 
     { 
      filesToConvert.Enqueue(file); 
     } 
     for (int i = 0; i < Environment.ProcessorCount; i++) 
     { 
      new Task(async() => 
      { 
       while(true) 
       { 
        if(filesToConvert.TryDequeue(out string path)) 
        { 
         await new Conversion().SetInput(path) 
             .UseMultiThread(false) 
             .SetOutput(Path.GetRandomFileName()) 
             .Start(); 
        } 
       } 
      }); 
     }