2015-05-20 3 views
1

Я новичок в SIP и RTP как. Мне удалось создать вызов SIP, но у меня все еще нет голоса для сеанса.RTP потоковая передача в SIP

Я понимаю, что мне нужно создать поток RTP и отправить пакеты. Но я не могу решить, с чего начать. Я нашел JMf-библиотеки (jar), но я не могу понять, как их использовать. Также я хочу воспроизвести аудио для человека, которого я вызываю во время транзакции.

Должен ли я запускать сеанс RTP внутри SIP INVITE или мне нужно создать сеанс RTP после ответа на вызов отдельно. Я не могу найти ответы на свой вопрос.

Также я хотел бы знать, как создать сеанс RTP, и я занимаюсь простым программированием на Java, я нашел учебное пособие с JMf, но с установкой. Я хочу, чтобы он знал, возможно ли это с помощью простого программирования на Java. У меня есть файл jmf-2.1.1e.jar. Я хотел бы знать, как его использовать.

public SoundSenderDemo(boolean isLocal, int RTPsocket) { 
     DatagramSocket rtpSocket = null; 
     DatagramSocket rtcpSocket = null; 
     int socket = RTPsocket; 


     try { 
      rtpSocket = new DatagramSocket(socket); 
      rtcpSocket = new DatagramSocket(socket+1); 
     } catch (Exception e) { 
      System.out.println("RTPSession failed to obtain port"); 
     } 

     rtpSession = new RTPSession(rtpSocket, rtcpSocket); 
     rtpSession.RTPSessionRegister(this,null, null); 
     Participant p = new Participant("sip:[email protected]",socket,(socket + 1)); 
//  rtpSession.addParticipant(p); 
     System.out.println("CNAME: " + rtpSession.CNAME()); 
     System.out.println("RTPSession: " + rtpSession.toString()); 
     System.out.println("Participant: " + rtpSession.getParticipants()); 
     System.out.println("unicast Receivers: " + rtpSession.getUnicastReceivers()); 

     this.local = isLocal; 
    } 

public void run() { 
     if(RTPSession.rtpDebugLevel > 1) { 
      System.out.println("-> Run()"); 
     } 
     File soundFile = new File(filename); 
     if (!soundFile.exists()) { 
      System.err.println("Wave file not found: " + filename); 
      return; 
     } 

     AudioInputStream audioInputStream = null; 
     try { 
      audioInputStream = AudioSystem.getAudioInputStream(soundFile); 
     } catch (UnsupportedAudioFileException e1) { 
      e1.printStackTrace(); 
      return; 
     } catch (IOException e1) { 
      e1.printStackTrace(); 
      return; 
     } 

     //AudioFormat format = audioInputStream.getFormat(); 
     AudioFormat.Encoding encoding = new AudioFormat.Encoding("PCM_SIGNED"); 
     AudioFormat format = new AudioFormat(encoding,((float) 8000.0), 16, 1, 2, ((float) 8000.0) ,false); 
     System.out.println(format.toString()); 


     if(! this.local) { 
      // To time the output correctly, we also play at the input: 
      auline = null; 
      DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); 

      try { 
       auline = (SourceDataLine) AudioSystem.getLine(info); 
       auline.open(format); 
      } catch (LineUnavailableException e) { 
       e.printStackTrace(); 
       return; 
      } catch (Exception e) { 
       e.printStackTrace(); 
       return; 
      } 

      if (auline.isControlSupported(FloatControl.Type.PAN)) { 
       FloatControl pan = (FloatControl) auline 
       .getControl(FloatControl.Type.PAN); 
       if (this.curPosition == Position.RIGHT) 
        pan.setValue(1.0f); 
       else if (this.curPosition == Position.LEFT) 
        pan.setValue(-1.0f); 
      } 

      auline.start(); 
     } 

     int nBytesRead = 0; 
     byte[] abData = new byte[EXTERNAL_BUFFER_SIZE]; 
     long start = System.currentTimeMillis(); 
     try { 
      while (nBytesRead != -1 && pktCount < 200) { 
       nBytesRead = audioInputStream.read(abData, 0, abData.length); 

       if (nBytesRead >= 0) { 
        rtpSession.sendData(abData); 
        //if(!this.local) { 
        auline.write(abData, 0, abData.length); 

        //dataCount += abData.length; 

        //if(pktCount % 10 == 0) { 
        // System.out.println("pktCount:" + pktCount + " dataCount:" + dataCount); 
        // 
        // long test = 0; 
        // for(int i=0; i<abData.length; i++) { 
        //  test += abData[i]; 
        // } 
        // System.out.println(Long.toString(test)); 
        //} 

        pktCount++; 
        //if(pktCount == 100) { 
        // System.out.println("Time!!!!!!!!! " + Long.toString(System.currentTimeMillis())); 
        //} 
        //System.out.println("yep"); 
       } 
       if(pktCount == 100) { 
        Enumeration<Participant> iter = this.rtpSession.getParticipants(); 
        //System.out.println("iter " + iter.hasMoreElements()); 
        Participant p = null; 

        while(iter.hasMoreElements()) { 
         p = iter.nextElement(); 

         String name = "name"; 
         byte[] nameBytes = name.getBytes(); 
         String data= "abcd"; 
         byte[] dataBytes = data.getBytes(); 


         int ret = rtpSession.sendRTCPAppPacket(p.getSSRC(), 0, nameBytes, dataBytes); 
         System.out.println("!!!!!!!!!!!! ADDED APPLICATION SPECIFIC " + ret); 
         continue; 
        } 
        if(p == null) 
         System.out.println("No participant with SSRC available :("); 
       } 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
      return; 
     } 
     System.out.println("Time: " + (System.currentTimeMillis() - start)/1000 + " s"); 

     try { Thread.sleep(200);} catch(Exception e) {} 

     this.rtpSession.endSession(); 

     try { Thread.sleep(2000);} catch(Exception e) {} 
     if(RTPSession.rtpDebugLevel > 1) { 
      System.out.println("<- Run()"); 
     } 
    } 

При отправке ACK

dialog.sendAck(ackRequest); 

//     System.out.println(ackRequest.toString()); 
       logger.debug(ackRequest.toString()); 
       aDemo = new SoundSenderDemo(false, RTPsocket); 
       RTPstart(); 


public void RTPstart(){ 
     // Start RTP Session 
     String file = "C:/universAAL/workspaces/SIPfinaltest withRTP/SIPfinaltest/JSIP/garfield_converted.wav"; 

//  SoundSenderDemo aDemo = new SoundSenderDemo(false); 

     aDemo.filename = args[0]; 
     aDemo.run(); 
     System.out.println("pktCount: " + aDemo.pktCount); 
    } 

Также в пригласите я поставил:

String sdpData = "v=0\n" + 
        "o=user1 795808818 480847547 IN IP4 "+localIP+"\n" + 
        "s=-\n" + 
        "c=IN IP4 "+localIP+"\n" + 
        "t=0 0\n" + 
        "m=audio 8000 RTP/AVP 0 8 101\n" + 
        "a=rtpmap:0 PCMU/8000\n" + 
        "a=rtpmap:8 PCMA/8000\n" + 
        "a=rtpmap:101 telephone-event/8000\n" + 
        "a=sendrecv"; 
      byte[] contents = sdpData.getBytes(); 

Это ответ:

SIP/2.0 200 OK 
Via: SIP/2.0/UDP 10.99.134.149:5060;branch=z9hG4bK-333831-44ef6fc075d847c6420a0f95b2022345;received=10.99.134.149;rport=5060 
From: <sip:[email protected]>;tag=-1209613008 
To: <sip:[email protected]>;tag=as12f64e9a 
Call-ID: [email protected] 
CSeq: 5 INVITE 
Server: Asterisk PBX 10.5.1 
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH 
Supported: replaces,timer 
Contact: <sip:[email protected]:5060> 
Content-Type: application/sdp 
Content-Length: 255 

v=0 
o=root 532626251 532626252 IN IP4 10.99.64.2 
s=Asterisk PBX 10.5.1 
c=IN IP4 10.99.64.2 
t=0 0 
m=audio 7758 RTP/AVP 8 101 
a=rtpmap:8 PCMA/8000 
a=rtpmap:101 telephone-event/8000 
a=fmtp:101 0-16 
a=silenceSupp:off - - - - 
a=ptime:20 
a=sendrecv 
+0

Может ли кто-нибудь помочь мне в этом? – gourig

ответ

0

, если вы заинтересованы в sip/rtp сеанс с использованием простого jav программирование, проверка http://peers.sourceforge.net/. Взгляните на страницу документации.

JMF устарел. В Интернете много java-rtp-стеков, просто Google «java rtp stack».

Когда настало время начать сеанс rtp? Это зависит, иногда вы можете запустить его только тогда, когда вы получите ответ 200 OK, иногда вам нужно создать его раньше, когда получен ответ 183.

Вы также можете создать сеанс rtp при отправке приглашения, а затем обновить его с правильной информацией, когда он будет получен (удаленный IP-адрес, порт, кодек).

+0

Привет, спасибо за ваш ответ. Мне удалось создать и сеанс RTP после отправки Ack. Но проблема в том, что сеанс RTP запускается локально, а звук воспроизводится на локальном ПК. Я не могу понять, где я могу обновить адрес, чтобы он воспроизводился на телефоне. Я вставляю свой код в вопрос. – gourig

+0

Удаленный IP-адрес и номер порта находятся в ответе 200 ok в sdp msg body. в строке c = здесь 10.99.64.2 у вас есть удаленный IP-адрес. И порт находится в строке m = здесь 7758. Убедитесь, что используется правый кодек. Здесь pcma. –

+0

Я использовал IP и порт из ответа, а аудио - это .wav-файл, который также представляет собой формат аудио PCM с 8-разрядной частотой дискретизации, частотой 8000 Гц. но по-прежнему не создает сеанс RTP. он воспроизводит аудио на моем ноутбуке. – gourig

Смежные вопросы