簡體   English   中英

不使用mjsip發送或接收RTP數據包

[英]RTP Packets are not being sent or received using mjsip

我正在使用mjsip sip堆棧進行軟件電話項目。 Mjsip僅支持g711或PCMA / PCMU編解碼器。 我已將G729添加到我的項目中。 當我構建項目時,它沒有顯示錯誤。 但是當手機連接時,呼叫建立,沒有語音傳輸,實際上我的應用程序不生成任何rtp數據包。 並在日志中顯示錯誤

java.lang.NullPointerException
RtpStreamReceiver - run -> Terminated.
    at local.media.RtpStreamReceiver.run(RtpStreamReceiver.java:171)

我沒找到錯誤。

這是我的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);

如果您有興趣, 這里是完整的項目源。

正如@gnat在評論中所說 - 很可能output_stream為null。

如果是這種情況,你應該檢查原因。 一個原因可能是:

private void init( SIPCodec sipCodec, OutputStream output_stream, DatagramSocket socket )

使用null參數調用,並覆蓋之前正確設置的值。

您可以通過將以下內容作為init中的第一行來記錄“who”調用特定函數:

System.out.println("My function is called from: "
+ Thread.currentThread().getStackTrace()[2].getClassName() + "."
+ Thread.currentThread().getStackTrace()[2].getMethodName());

對於使用RTP Java媒體框架傳輸語音很有用。 從oracle的網站你可以得到jmf.exe。 你可以使用那個Api傳輸語音。 也可以使用傳輸語音的串聯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM