我正在做一个软电话项目使用mjsip sip栈。Mjsip仅支持g711或PCMA/PCMU编解码器。我已经将G729添加到我的项目中。当我构建这个项目时,它没有显示任何错误。但当电话连接上时,呼叫就建立起来了,没有语音传输,实际上我的应用程序不会生成任何rtp数据包。在日志中显示如下错误
java.lang.NullPointerException
RtpStreamReceiver - run -> Terminated.
at local.media.RtpStreamReceiver.run(RtpStreamReceiver.java:171)我找不到bug。
这是我的RtpStreamReceiver.java类。
package local.media;
import local.net.RtpPacket;
import local.net.RtpSocket;
import java.io.*;
import java.net.DatagramSocket;
import org.flamma.codec.SIPCodec;
/** RtpStreamReceiver is a generic stream receiver.
* It receives packets from RTP and writes them into an OutputStream.
*/
public class RtpStreamReceiver extends Thread {
public static int RTP_HEADER_SIZE = 12;
private long start = System.currentTimeMillis();
public static final int SO_TIMEOUT = 200; // Maximum blocking time, spent waiting for reading new bytes [milliseconds]
private SIPCodec sipCodec = null; // Sip codec to be used on audio session
private RtpSocket rtp_socket = null;
private boolean socketIsLocal = false; // Whether the socket has been created here
private boolean running = false;
private int timeStamp = 0;
private int frameCounter = 0;
private OutputStream output_stream;
public RtpStreamReceiver( SIPCodec sipCodec, OutputStream output_stream, int local_port )
{
try {
DatagramSocket socket = new DatagramSocket( local_port );
socketIsLocal = true;
init( sipCodec, output_stream, socket );
start = System.currentTimeMillis();
}
catch ( Exception e ) {
e.printStackTrace();
}
}
public RtpStreamReceiver( SIPCodec sipCodec, OutputStream output_stream, DatagramSocket socket )
{
init( sipCodec, output_stream, socket );
}
/** Inits the RtpStreamReceiver */
private void init( SIPCodec sipCodec, OutputStream output_stream, DatagramSocket socket )
{
this.sipCodec = sipCodec;
this.output_stream = output_stream;
if ( socket != null ) {
rtp_socket = new RtpSocket( socket );
}
}
/** Whether is running */
public boolean isRunning()
{
return running;
}
/** Stops running */
public void halt()
{
running = false;
}
/** Runs it in a new Thread. */
public void run()
{
if ( rtp_socket == null )
{
println( "run", "RTP socket is null." );
return;
}
byte[] codedBuffer = new byte[ sipCodec.getIncomingEncodedFrameSize() ];
byte[] internalBuffer = new byte[sipCodec.getIncomingEncodedFrameSize() + RTP_HEADER_SIZE ];
RtpPacket rtpPacket = new RtpPacket( internalBuffer, 0 );
running = true;
try {
rtp_socket.getDatagramSocket().setSoTimeout( SO_TIMEOUT );
float[] decodingBuffer = new float[ sipCodec.getIncomingDecodedFrameSize() ];
int packetCount = 0;
println( "run",
"internalBuffer.length = " + internalBuffer.length
+ ", codedBuffer.length = " + codedBuffer.length
+ ", decodingBuffer.length = " + decodingBuffer.length + "." );
while ( running ) {
try {
rtp_socket.receive( rtpPacket );
frameCounter++;
if ( running ) {
byte[] packetBuffer = rtpPacket.getPacket();
int offset = rtpPacket.getHeaderLength();
int length = rtpPacket.getPayloadLength();
int payloadType = rtpPacket.getPayloadType();
if(payloadType < 20)
{
System.arraycopy(packetBuffer, offset, codedBuffer, 0, sipCodec.getIncomingEncodedFrameSize());
timeStamp = (int)(System.currentTimeMillis() - start);
output_stream.write(codedBuffer,offset,length);
}
}
}
catch ( java.io.InterruptedIOException e ) {
}
}
}
catch ( Exception e ) {
running = false;
e.printStackTrace();
}
// Close RtpSocket and local DatagramSocket.
DatagramSocket socket = rtp_socket.getDatagramSocket();
rtp_socket.close();
if ( socketIsLocal && socket != null ) {
socket.close();
}
// Free all.
rtp_socket = null;
println( "run", "Terminated." );
}
/** Debug output */
private static void println( String method, String message ) {
System.out.println( "RtpStreamReceiver - " + method + " -> " + message );
}第171行是:output_stream.write(codedBuffer,offset,length);
如果你感兴趣,here是完整的项目源代码。
发布于 2012-07-03 02:25:42
正如@gnat在评论中所说的--最有可能的是output_stream是空的。
如果是这样的话,你应该检查为什么。其中一个原因可能是:
private void init( SIPCodec sipCodec, OutputStream output_stream, DatagramSocket socket )
使用null参数调用,并且它会重写之前正确设置的值。
您可以通过将以下内容作为init中的第一行来记录调用特定函数的“谁”:
System.out.println("My function is called from: "
+ Thread.currentThread().getStackTrace()[2].getClassName() + "."
+ Thread.currentThread().getStackTrace()[2].getMethodName());发布于 2012-07-19 13:29:04
对于使用RTP传输语音的Java媒体框架非常好用。在oracle的网站上,你可以获得jmf.exe。并且你可以使用该Api传输语音。传输语音的编码也是可用的。
https://stackoverflow.com/questions/9307084
复制相似问题