的MP3不会与JMF流 [英] MP3 won't stream with JMF
问题描述
基本思路是访问MP3档案,并通过RTP流发送给其他客户,谁想玩那首歌曲。
Basic idea is to access .mp3 file and send it through RTP stream to other client, who will want to play that song.
下面是RTPServer.java,我在网上找到并修改我的胃口。
Here is RTPServer.java, which I found online and modified it to my liking.
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:
And here is receiving end, 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,客户端将无法播放。我得到:
I figured, it successfully sends the whatever file I choose, but when I send .mp3, Client won't play it. I get:
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完美发送。所以我的猜测是被之前发送的格式设置。我试图改变格式其他支持的格式,但然后我得到一大堆其他的错误。
Interesting thing is, .wav is sent perfectly. So my guess was is the format set prior to sending. And I tried changing format to some other supported format, but then I get bunch of other errors.
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
最后,我打开JMStudio的(内置的应用程序发送/接收JMF媒体流),当我尝试流.MP3,我得到确切的同样的错误运行我的应用程序时。 JMF设置了罚款,我检查PATH和CLASSPATH,也是我安装mp3plugin这也是设置的罚款。一切似乎都很好,但它只是不工作!至少.MP3不是。
那么,如何才能让.MP3去到另一端?
Finally, I opened JMStudio (the built-in app for sending/receiving media streams in JMF), and when I try to stream .mp3, I get exact same error as when running my app. JMF is set up fine, I checked PATH and CLASSPATH, also I installed mp3plugin which is also setup fine. Everything seems fine, but it just doesn't work! At least .mp3 is not. So, how can I make .mp3 "go to the other end"?
推荐答案
解决。
所有我需要做的是在构造函数发送/接收器添加这些行。
All I had to do is add these lines in constructor for 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的工作不......不,我不在乎了。
Might help somebody else with this problem :) Still don't know why JMStudio isn't working... Not that I care anymore.
这篇关于的MP3不会与JMF流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!