2011-01-29 14 views
9

Podstawowym pomysłem jest dostęp do pliku .mp3 i wysłanie go za pośrednictwem strumienia RTP do innego klienta, który będzie chciał go odtworzyć.MP3 nie będzie przesyłany strumieniowo za pomocą JMF

Oto RTPServer.java, którą znalazłem online i zmodyfikowałem zgodnie z moimi upodobaniami.

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); 
} 
    } 
} 

I tu jest odbiorczej 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()); 
} 
    } 
} 

Pomyślałem, że z powodzeniem przesyła cokolwiek pliku wybiorę, ale kiedy wysłać .mp3, klient nie będzie grać. Otrzymuję:

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

Interesujące jest to, że .wav jest wysyłany idealnie. Tak więc zgaduję, że to zestaw formatów przed wysłaniem. Próbowałem zmienić format na inny obsługiwany format, ale dostaję też mnóstwo innych błędów.

 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] 

Wreszcie otworzył JMStudio (wbudowany w aplikację do wysyłania/odbierania strumieni mediów w JMF) i gdy próbuję strumień .mp3, mam dokładnie ten sam błąd, jak wtedy, gdy uruchomiony Moje app. JMF jest ustawiony dobrze, sprawdziłem PATH i CLASSPATH, również zainstalowałem mp3plugin, który również jest ustawiony dobrze. Wszystko wydaje się w porządku, ale po prostu nie działa! Przynajmniej .mp3 nie jest. Jak więc utworzyć .mp3 "przejdź na drugi koniec"?

Odpowiedz

8

Rozwiązany.

Wszystko, co musiałem zrobić, to dodać te linie do konstruktora dla nadawcy/odbiorcy.

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); 

może pomóc komuś innemu z tym problemem :) Nadal nie wiem dlaczego JMStudio nie działa ... Nie dlatego, że zależy mi już.

+1

Czy klient/serwer musi być w różnych wersjach lub czy oba działają na jednym, tj. Na połączeniu lokalnego hosta / – LmC

Powiązane problemy