2011-01-29 16 views
9

La idea básica es acceder al archivo .mp3 y enviarlo a través de la transmisión RTP a otro cliente, que querrá reproducir esa canción.MP3 no se transmitirá con JMF

Aquí está RTPServer.java, que encontré en línea y lo modifiqué a mi gusto.

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

Y aquí está recibiendo final, 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()); 
} 
    } 
} 

que pensé, envía correctamente el archivo de todo lo que desea, pero cuando envío .mp3, cliente no jugarlo. Obtengo:

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

Lo interesante es que .wav se envía perfectamente. Así que mi conjetura fue el formato establecido antes del envío. Intenté cambiar el formato a otro formato admitido, pero luego recibí muchos otros errores.

 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] 

Finalmente, abrí JMStudio (el incorporado en la aplicación para el envío/recepción de flujos de medios en JMF), y cuando trato de transmitir .mp3, consigo exacta mismo error que cuando se ejecuta mi aplicación. JMF está bien configurado, revisé PATH y CLASSPATH, también instalé mp3plugin, que también está bien configurado. ¡Todo parece estar bien, pero simplemente no funciona! Al menos .mp3 no lo es. Entonces, ¿cómo puedo hacer que el .mp3 "vaya al otro extremo"?

Respuesta

8

Resuelto.

Todo lo que tuve que hacer es agregar estas líneas en el constructor para el remitente/receptor.

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

podía ayudar a otros con este problema :) todavía no saben qué JMStudio no está funcionando ... No es que me importa más.

+1

¿El cliente/servidor tiene que estar en diferentes ips o ambos trabajan en el uno es tanto de localhost / – LmC