我想使用RTP格式的JMF 2.1.1e捕获和流式传输音频。我写了一个简单的发射器,我可以发送和接收音频。但是当我在Wireshark中看到时,我看到数据包为UDP。请问有人能指出我的问题吗。
这是我负责音频捕获和传输的功能。
public void captureAudio(){
// Get the device list for ULAW
Vector devices = captureDevices();
CaptureDeviceInfo captureDeviceInfo = null;
if (devices.size() > 0) {
//get the first device from the list and cast it as CaptureDeviceInfo
captureDeviceInfo = (CaptureDeviceInfo) devices.firstElement();
}
else {
// exit if we could not find the relevant capturedevice.
System.out.println("No such device found");
System.exit(-1);
}
Processor processor = null;
try {
//Create a Processor for the specified media.
processor = Manager.createProcessor(captureDeviceInfo.getLocator());
} catch (IOException ex) {
System.err.println(ex);
} catch (NoProcessorException ex) {
System.err.println(ex);
}
//Prepares the Processor to be programmed.
//puts the Processor into the Configuring state.
processor.configure();
//Wait till the Processor configured.
while (processor.getState() != Processor.Configured){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//Sets the output content-type for this Processor
processor.setContentDescriptor(CONTENT_DESCRIPTOR);
/**
ContentDescriptor CONTENT_DESCRIPTOR
= new ContentDescriptor(ContentDescriptor.RAW_RTP);
*/
//Gets a TrackControl for each track in the media stream.
TrackControl track[] = processor.getTrackControls();
boolean encodingOk = false;
//searching through tracks to get a supported audio format track.
for (int i = 0; i < track.length; i++) {
if (!encodingOk && track[i] instanceof FormatControl) {
if (((FormatControl)
track[i]).setFormat( new AudioFormat(AudioFormat.ULAW_RTP, 8000, 8, 1) ) == null)
{
track[i].setEnabled(false);
}
else {
encodingOk = true;
track[i].setEnabled(encodingOk);
System.out.println("enc: " + i);
}
} else {
// we could not set this track to ULAW, so disable it
track[i].setEnabled(false);
}
}
//If we could set this track to ULAW we proceed
if (encodingOk){
processor.realize();
while (processor.getState() != Processor.Realized){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
DataSource dataSource = null;
try {
dataSource = processor.getDataOutput();
} catch (NotRealizedError e) {
e.printStackTrace();
}
try {
String url= "rtp://192.168.1.99:49150/audio/1";
MediaLocator m = new MediaLocator(url);
DataSink d = Manager.createDataSink(dataSource, m);
d.open();
d.start();
System.out.println("transmitting...");
processor.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
请问,如果您发现任何不正确或含糊的内容。 提前致谢。 :)
澄清:我有一个用于RTP流的 C#代码。当我使用 wireshark 捕获数据时,我可以将它们视为 RTP ,但问题是当我从 JMF wireshark捕获数据流时将它们显示为 UDP 。我的问题是,为什么?
我知道UDP和RTP之间的区别。
答案 0 :(得分:8)
RTP是应用层, UDP是传输层, 那是不一样的水平! 维基百科有助于详细解释。 因此,您的数据将作为UDP“帧”中的RTP流发送
小概述......
应用层:
* DHCP
* DHCPv6
* DNS
* FTP
* HTTP
* IMAP
* IRC
* LDAP
* MGCP
* NNTP
* BGP
* NTP
* POP
* RPC
* RTP
* RTSP
* RIP
* SIP
* SMTP
* SNMP
* SOCKS
* SSH
* Telnet
* TLS/SSL
* XMPP
* (more)
传输层
* TCP
* UDP
* DCCP
* SCTP
* RSVP
* (more)
互联网图层
* IP
o IPv4
o IPv6
* ICMP
* ICMPv6
* ECN
* IGMP
* IPsec
* (more)
链接图层
* ARP/InARP
* NDP
* OSPF
* Tunnels
o L2TP
* PPP
* Media access control
o Ethernet
o DSL
o ISDN
o FDDI
* (more)
答案 1 :(得分:5)
如果我正确理解您的问题,您想知道为什么RTP数据包在wireshark中不被识别为RTP数据包。根据我的经验,如果wireshark没有足够的有关RTP会话的信息,情况就是这样。
例如:1)如果我嗅探使用RTSP或SIP和SDP设置的RTP会话,则wireshark将显示检测RTP。 2)然而,在我使用本地SDP描述设置会话的另一个应用程序中,数据包显示为UDP。在第二种情况下,wireshark看到了RTP数据包,但缺乏将它们归类为RTP的信息。由于RTP通常位于UDP之上,而wireshark可以对UDP数据包进行分类,因此它们被归类为。
仅供参考,您可以从流中选择您知道 RTP的数据包,然后选择“解码为”。然后从协议列表中为相应的流选择RTP(如果适用,则选择另一个的RTCP),然后wireshark将数据包显示为RTP,您将能够看到数据包信息。
我不确定这是否是您特定情况下的原因,但是您的JMF和您的C#示例之间可能存在信号差异?听起来你可能正在为C#应用程序使用SIP,而JMF没有使用它?