2016-03-27 22 views
2

Wenn Sie mplayer starten, wird die Position und Länge des Playbacks (neben einigen anderen Informationen) angezeigt, was ich annehmen würde, stdout.Console-Ausgabe von MPlayer lesen, um die Position/Länge des Tracks zu analysieren

Hier ist ein Beispiel für die Ausgabe von MPlayer:

MPlayer2 2.0-728-g2c378c7-4+b1 (C) 2000-2012 MPlayer Team 
Cannot open file '/home/pi/.mplayer/input.conf': No such file or directory 
Failed to open /home/pi/.mplayer/input.conf. 
Cannot open file '/etc/mplayer/input.conf': No such file or directory 
Failed to open /etc/mplayer/input.conf. 

Playing Bomba Estéreo - La Boquilla [Dixone Remix].mp3. 
Detected file format: MP2/3 (MPEG audio layer 2/3) (libavformat) 
[mp3 @ 0x75bc15b8]max_analyze_duration 5000000 reached 
[mp3 @ 0x75bc15b8]Estimating duration from bitrate, this may be inaccurate 
[lavf] stream 0: audio (mp3), -aid 0 
Clip info: 
album_artist: Bomba Estéreo 
genre: Latin 
title: La Boquilla [Dixone Remix] 
artist: Bomba Estéreo 
TBPM: 109 
TKEY: 11A 
album: Unknown 
date: 2011 
Load subtitles in . 
Selected audio codec: MPEG 1.0/2.0/2.5 layers I, II, III [mpg123] 
AUDIO: 44100 Hz, 2 ch, s16le, 320.0 kbit/22.68% (ratio: 40000->176400) 
AO: [pulse] 44100Hz 2ch s16le (2 bytes per sample) 
Video: no video 
Starting playback... 
A: 47.5 (47.4) of 229.3 (03:49.3) 4.1% 

Die letzte Zeile (A: 47.5 (47.4) of 229.3 (03:49.3) 4.1%) ist, was ich versuche aber zu lesen, aus irgendeinem Grunde, es ist nie von den Process.OutputDataReceived Ereignishandler empfangen.

Fehle ich etwas? Verwendet MPlayer eine nicht-standardmäßige Art der Ausgabe der "A:" Zeile an die Konsole?

Hier ist der Code, falls es hilft:

Public Overrides Sub Play() 
    player = New Process() 
    player.EnableRaisingEvents = True 

    With player.StartInfo 
     .FileName = "mplayer" 
     .Arguments = String.Format("-ss {1} -endpos {2} -volume {3} -nolirc -vc null -vo null ""{0}""", 
            tmpFileName, 
            mTrack.StartTime, 
            mTrack.EndTime, 
            100) 

     .CreateNoWindow = False 
     .UseShellExecute = False 
     .RedirectStandardOutput = True 
     .RedirectStandardError = True 
     .RedirectStandardInput = True 
    End With 

    AddHandler player.OutputDataReceived, AddressOf DataReceived 
    AddHandler player.ErrorDataReceived, AddressOf DataReceived 
    AddHandler player.Exited, Sub() KillPlayer() 

    player.Start() 
    player.BeginOutputReadLine() 
    player.BeginErrorReadLine() 

    waitForPlayer.WaitOne() 

    KillPlayer() 
End Sub 

Private Sub DataReceived(sender As Object, e As DataReceivedEventArgs) 
    If e.Data = Nothing Then Exit Sub 

    If e.Data.Contains("A: ") Then 
     ' Parse the data 
    End If 
End Sub 
+0

Uhr/proc/$ MPLAYERPID/fd/* (als root), dies herauszufinden. –

+0

Ich versuchte cat/tail für alle "Dateien", die unter/proc/$ MPLAYERPID/fd/erstellt wurden, aber keiner von ihnen scheint irgendwelche Verweise auf die "A:" Zeile zu enthalten. Tatsächlich scheinen die meisten von ihnen leer zu sein. – xfx

Antwort

1

ich das gleiche Problem mit einer anderen Anwendung gefunden, die mehr oder weniger in einer ähnlichen Art und Weise (dBpoweramp), in meinem Fall arbeitet, war das Problem, dass der Prozessausgang verwendet Unicode-Codierung die stdout Puffer zu schreiben, so habe ich, um den StandardOutputEncoding und Standarderror zu Unicode Lage Lesen beginnen zu können.

Ihr Problem scheint das gleiche zu sein, denn wenn "A" nicht in der von Ihnen veröffentlichten Ausgabe gefunden wird, die das vorhandene "A" eindeutig anzeigt, dann bedeutet das wahrscheinlich, dass das Zeichen beim Einlesen in die aktuelle Kodierung von Ihnen abweicht benutzen um die Ausgabe zu lesen.

Versuchen Sie also, beim Lesen der Prozessausgabe die richtige Codierung festzulegen, und versuchen Sie, sie auf Unicode einzustellen.

2

Offenbar ist die einzige Lösung mplayer in "Slave" Modus ausgeführt werden, wie hier erklärt: http://www.mplayerhq.hu/DOCS/tech/slave.txt

In diesem Modus können wir sende Befehle an mplayer (via stdin) und die Antwort (falls vorhanden) wird über stdout gesendet.

Hier ist eine sehr einfache Implementierung, die MPlayer der aktuelle Position anzeigt (in Sekunden):

using System; 
using System.Threading; 
using System.Diagnostics; 
using System.Collections.Generic; 

namespace TestMplayer { 
    class MainClass { 
     private static Process player; 

     public static void Main(string[] args) { 
      String fileName = "/home/pi/Documents/Projects/Raspberry/RPiPlayer/RPiPlayer/bin/Electronica/Skrillex - Make It Bun Dem (Damian Marley) [Butch Clancy Remix].mp3"; 
      player = new Process(); 
      player.EnableRaisingEvents = true; 

      player.StartInfo.FileName = "mplayer"; 
      player.StartInfo.Arguments = String.Format("-slave -nolirc -vc null -vo null \"{0}\"", fileName); 

      player.StartInfo.CreateNoWindow = false; 
      player.StartInfo.UseShellExecute = false; 
      player.StartInfo.RedirectStandardOutput = true; 
      player.StartInfo.RedirectStandardError = true; 
      player.StartInfo.RedirectStandardInput = true; 

      player.OutputDataReceived += DataReceived; 

      player.Start(); 
      player.BeginOutputReadLine(); 
      player.BeginErrorReadLine(); 

      Thread getPosThread = new Thread(GetPosLoop); 
      getPosThread.Start(); 
     } 

     private static void DataReceived(object o, DataReceivedEventArgs e) { 
      Console.Clear(); 
      Console.WriteLine(e.Data); 
     } 

     private static void GetPosLoop() { 
      do { 
       Thread.Sleep(250); 
       player.StandardInput.Write("get_time_pos" + Environment.NewLine); 
      } while(!player.HasExited); 
     } 
    } 
}