2011-01-29 35 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

已解決。

我只需要在sender/receiver的構造函數中添加這些行。

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

客戶端/服務器是否必須處於不同的IP位置,還是都在同一個位置工作,即本地主機/ – LmC 2013-04-18 11:22:08