2011-01-29 7 views
9

基本的な考え方は、.mp3ファイルにアクセスしてRTPストリームを通して、その曲を再生したい他のクライアントに送信することです。MP3はJMFでストリーミングされません

ここにはRTPServer.javaがありますが、これは私がオンラインで見つけて好きに変更したものです。

package server; 

import java.net.InetAddress; 
import javax.media.rtp.*; 
import javax.media.rtp.rtcp.*; 
import javax.media.*; 
import javax.media.protocol.*; 
import javax.media.control.*; 

public class RTPServer implements ControllerListener, Runnable { 
    private boolean realized = false; 
    private boolean configured = false; 
    private String ipAddress; 
    Processor p; 
    MediaLocator src; 

    public static void main (String[] args) { 
     RTPServer rtp = new RTPServer("192.168.1.101", "04 - Blue.mp3"); 
     Thread t = new Thread(rtp); 
     t.start(); 
    } 

    public RTPServer(String ip, String song) { 
     ipAddress = ip; 
String srcFile = "Muzika\\" + song; 
src = new MediaLocator("file:" + srcFile); 

    } 

    private void setTrackFormat(Processor p) { 
// Get the tracks from the processor 
TrackControl [] tracks = p.getTrackControls(); 
// Do we have atleast one track? 
if (tracks == null || tracks.length < 1) { 
    System.out.println("Couldn't find tracks in processor"); 
    System.exit(1); 
} 

// Set the output content descriptor to RAW_RTP 
// This will limit the supported formats reported from 
// Track.getSupportedFormats to only valid RTP formats. 
ContentDescriptor cd = new ContentDescriptor(ContentDescriptor.RAW_RTP); 
p.setContentDescriptor(cd); 

Format supported[]; 
Format chosen; 
boolean atLeastOneTrack = false; 

// Program the tracks. 
for (int i = 0; i < tracks.length; i++) { 
    Format format = tracks[i].getFormat(); 
      System.out.println("Trenutni format je " +format.getEncoding()); 
    if (tracks[i].isEnabled()) { 
    supported = tracks[i].getSupportedFormats(); 
    for (int n = 0; n < supported.length; n++) 
     System.out.println("Supported format: " + supported[n]); 

    // We've set the output content to the RAW_RTP. 
    // So all the supported formats should work with RTP. 
    // We'll just pick the first one. 

    if (supported.length > 0) { 
     chosen = supported[0]; // this is where I tried changing formats 
     tracks[i].setFormat(chosen); 
     System.err.println("Track " + i + " is set to transmit as: " +chosen); 
     atLeastOneTrack = true; 
    } else 
     tracks[i].setEnabled(false); 
    } else 
    tracks[i].setEnabled(false); 
} 
    } 

    private void transmit(Processor p) { 
try { 
    DataSource output = p.getDataOutput(); 
    PushBufferDataSource pbds = (PushBufferDataSource) output; 
    RTPManager rtpMgr = RTPManager.newInstance(); 
    SessionAddress localAddr, destAddr; 
    SendStream sendStream; 
    int port = 42050; 
    SourceDescription srcDesList[]; 
    localAddr = new SessionAddress(InetAddress.getLocalHost(), port); 
    InetAddress ipAddr = InetAddress.getByName(ipAddress); 
    destAddr = new SessionAddress(ipAddr, port); 
    rtpMgr.initialize(localAddr); 
    rtpMgr.addTarget(destAddr); 
    sendStream = rtpMgr.createSendStream(output, 0); 
    sendStream.start(); 
    System.err.println("Created RTP session: " + ipAddress + " " + port); 
    p.start(); 
} catch(Exception e) { 
    e.printStackTrace(); 
} 
    } 

    public synchronized void controllerUpdate(ControllerEvent evt) { 
if (evt instanceof RealizeCompleteEvent) { 
    realized = true; 
} else if (evt instanceof ConfigureCompleteEvent) { 
    configured = true; 
} else if (evt instanceof EndOfMediaEvent) { 
    System.exit(0); 
} else { 
    // System.out.println(evt.toString()); 
} 
    } 

    public void run() { 

try { 
    p = Manager.createProcessor(src); 
    p.addControllerListener(this); 
    p.configure(); 
    while (! configured) { 
    try { 
     Thread.currentThread().sleep(100L);; 
    } catch (InterruptedException e) { 
     // ignore 
    } 
    } 

    setTrackFormat(p); 
    p.setContentDescriptor(new ContentDescriptor(ContentDescriptor.RAW_RTP)); 

    p.realize(); 
    while (! realized) { 
    try { 
     Thread.currentThread().sleep(100L);; 
    } catch (InterruptedException e) { 
     // ignore 
    } 
    } 
    transmit(p); 

} catch(Exception e) { 
    e.printStackTrace(); 
    System.exit(1); 
} 
    } 
} 

そしてここで終わり、RTPClient受信している:

package client; 


import javax.media.*; 

public class RTPClient implements ControllerListener, Runnable { 

    Player p; 
    MediaLocator src; 

    public static void main(String[] args) { 
     RTPClient rtp = new RTPClient("192.168.1.100"); 
     Thread t = new Thread(rtp); 
     t.start(); 

    } 

    public RTPClient(String ip) { 
String srcUrl = "rtp://" + ip + ":42050/audio/1"; 
DataSink sink; 
src = new MediaLocator(srcUrl); 
    } 
    public void run() { 
     try { 
    p = Manager.createPlayer(src); 
    p.addControllerListener(this); 
    p.start(); 
} catch(Exception e) { 
    e.printStackTrace(); 
    System.exit(1); 
} 
    } 

    public synchronized void controllerUpdate(ControllerEvent evt) { 
if (evt instanceof EndOfMediaEvent) { 
    System.exit(0); 
} else { 
    System.out.println(evt.toString()); 
} 
    } 
} 

を私はそれが正常に私が選択したが、私は.MP3を送信するとき、クライアントはそれを再生しませんどんなファイルを送信し、考え出しました。私は:

RTP Handler internal error: 
javax.media.ControllerErrorEvent[[email protected],message=Internal 
module [email protected]: failed to handle a data 
format change!] 

興味深いことに、.wavが完全に送信されます。だから私の推測は、送信する前に設定されたフォーマットです。そして、フォーマットをサポートされている他のフォーマットに変更しようとしましたが、その後他のエラーが発生します。

 Failed to build a graph for the given custom options. 
Failed to realize: [email protected] 
    Cannot build a flow graph with the customized options: 
    Unable to transcode format: mpegaudio, 48000.0 Hz, 16-bit, Stereo, LittleEndian, Signed, 20000.0 frame rate, FrameSize=11264 bits 
     to: ULAW/rtp, 8000.0 Hz, 8-bit, Stereo 
     outputting to: RAW/RTP 
Error: Unable to realize [email protected] 

最後に、私はJMStudioを開いた(送信/ JMFにメディアストリームを受信するためのアプリ内蔵)、と私は.MP3ストリーミングしようとしたとき、私は私のアプリを実行したときとまったく同じエラーを取得します。 JMFはうまくセットアップされていますが、PATHとCLASSPATHを確認しました。また、設定済みのmp3pluginもインストールしました。すべてうまく見えますが、うまくいきません!少なくとも.mp3はそうではありません。 それでは、.mp3を「もう一方の端に行く」ようにするにはどうすればよいですか?

答えて

8

解決済み。

私がしなければならなかったのは、これらの行を送信者/受信者のコンストラクタに追加することでした。

Format input1 = new AudioFormat(AudioFormat.MPEGLAYER3); 
Format input2 = new AudioFormat(AudioFormat.MPEG); 
Format output = new AudioFormat(AudioFormat.LINEAR); 
PlugInManager.addPlugIn(
     "com.sun.media.codec.audio.mp3.JavaDecoder", 
     new Format[]{input1, input2}, 
     new Format[]{output}, 
     PlugInManager.CODEC); 

は、この問題を他の誰かを助けるかもしれない:) JMStudioが機能しない理由 はまだ知らない...私はもう気にしないこと。

+1

クライアント/サーバが異なるサーバに接続されている必要がありますか、または両方で動作しているかどうか、つまりローカルホスト/ – LmC