2016-03-27 5 views
2

mplayerを実行すると、再生トラックの位置と長さ(他の情報の中でも)が、私が想定していると思われるものから標準出力まで表示されます。mplayerからコンソールの出力を読み込んでトラックの位置/長さを解析する

はここでは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% 

最後の行(A: 47.5 (47.4) of 229.3 (03:49.3) 4.1%)が何らかの理由で、それはProcess.OutputDataReceivedイベントハンドラが受信したことがないですが、私は読んしようとしているものですが、。

何か不足していますか? mplayerはコンソールに「A:」行を出力する非標準的な方法を使用していますか?

ここでそれが助け場合のコードです:

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

ウォッチ/ procの/ $ MPLAYERPID/FD/*(ルートなど)は、これを見つけるために。 –

+0

私は/ proc/$ MPLAYERPID/fd /の下に作成されたすべての "ファイル"に対してcat/tailを試みましたが、どれも "A:"行への参照を含んでいないようです。実際、それらのほとんどは空であるように見えます。 – xfx

答えて

1

私は同様の方法(dbPowerAmp)に多かれ少なかれを作品別のアプリケーションと同じ問題が、私の場合には、問題があることがわかったが、プロセス出力は、標準出力バッファを書き込むユニコードエンコーディングを使用し、私はでき開始読取ことがユニコードにStandardOutputEncodingはStandardErrorを設定しなければなりません。

「A」が出力された出力の中に「A」が見つからない場合は、既存の「A」が示されているため、現在のエンコーディングで読むときにその文字が異なる可能性があるためです。出力を読み取るために使用しています。

したがって、プロセス出力を読むときに適切なエンコーディングを設定して、Unicodeに設定してみてください。我々はできるこのモードではhttp://www.mplayerhq.hu/DOCS/tech/slave.txt

:ここで説明したように

2

どうやら、唯一の解決策は、 "スレーブ" モードではmplayerを実行することですmplayerにコマンドを(stdin経由で)送信し、応答があればそれをstdout経由で送信します。

ここで(秒)のmplayerの現在位置を表示する非常に単純な実装です:

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); 
     } 
    } 
} 
関連する問題