MP3 не будет транслироваться с JMF - PullRequest
9 голосов
/ 30 января 2011

Основная идея - получить доступ к файлу .mp3 и отправить его через поток RTP другому клиенту, который захочет воспроизвести эту песню.

Вот файл RTPServer.java, который я нашел в Интернете и изменил в своем.симпатия.</p> <pre><code> 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[source=com.sun.media.content.unknown.Handler@9ed927,message=Internal
module com.sun.media.BasicRendererModule@1386000: failed to handle a data
format change!]

Интересно, что .wav отправляется отлично.Таким образом, я предполагаю, что формат был установлен до отправки.И я попытался изменить формат на другой поддерживаемый формат, но затем я получил кучу других ошибок.

Failed to build a graph for the given custom options.
Failed to realize: com.sun.media.ProcessEngine@eee36c
  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 com.sun.media.ProcessEngine@eee36c
</code>

Наконец, я открыл JMStudio (встроенное приложение для отправки / получения потоков мультимедиа в JMF),и при попытке потоковой передачи .mp3 я получаю ту же ошибку, что и при запуске моего приложения.JMF настроен нормально, я проверил PATH и CLASSPATH, также я установил mp3plugin, который также настроен нормально.Все вроде хорошо, но просто не работает!По крайней мере .mp3 нет.Итак, как я могу сделать .mp3 "перейти на другой конец"?

1 Ответ

8 голосов
/ 30 января 2011

решаемая.

Все, что мне нужно было сделать, это добавить эти строки в конструкторе для отправителя / получателя.

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 неработает ... Не то чтобы меня это больше волновало.

...