为啥 JMF 不使用 Mjsip 处理音频流?

Posted

技术标签:

【中文标题】为啥 JMF 不使用 Mjsip 处理音频流?【英文标题】:Why JMF is not working on Audio streaming with Mjsip?为什么 JMF 不使用 Mjsip 处理音频流? 【发布时间】:2012-02-21 00:40:25 【问题描述】:

我正在使用 Mjsip 创建一个软件电话。在代码中有音频串流的三种类型选项。

    使用 JMF(Java 媒体框架) 使用 Java 音频 使用 RAT(强大的音频工具)

我没有使用 RAT。它的值是我自己弄错的。这是下面调用 JMF 的代码:

public JMFAudioLauncher(int local_port, String remote_addr, int remote_port, int direction, Log logger)
  
    log=logger;
    localport=local_port;
    remoteport=remote_port;
    remoteaddr=remote_addr;
    // Patch for working with JMF with local streams
    if (remote_addr.startsWith("127."))
      
        printLog("Patch for JMF: replaced local destination address "+remote_addr+" with 255.255.255.255");
        remote_addr="255.255.255.255";
    
    dir=direction;
    if (dir>=0) sender=new JMediaSender("audio",null,remote_addr,remote_port);
    if (dir<=0) receiver=new JMediaReceiver("audio",local_port,null);


/** Starts media application */
public boolean startMedia()
  
    printLog("launching JMF-Audio...");
    String err1=null, err2=null;

    if (sender!=null) err1=sender.start();
    if (err1!=null) printLog("Error trying to send audio stream: "+err1);    

    if (receiver!=null) err2=receiver.start();
    if (err2!=null) printLog("Error trying to receive audio stream: "+err2);    

    return (err1==null && err2==null);      


/** Stops media application */
public boolean stopMedia()
  
    String err1=null, err2=null;

    if (sender!=null) err1=sender.stop();      
    if (err1!=null) printLog("Error stopping audio sender: "+err1);    

    if (receiver!=null) err2=receiver.stop();      
    if (err2!=null) printLog("Error stopping audio receiver: "+err2);    

    return (err1==null && err2==null);      

但它没有启动。我仍然可以用我的软电话通话。但在日志中显示...

UA: REGISTRATION
UA: Registration success: 200 OK
UA: INCOMING
UA: CONFIRMED/CALL
UA: Error trying to create the JMFAudioLauncher
AudioInput: TargetDataLine: com.sun.media.sound.DirectAudioDevice$DirectTDL@239525
AudioOutput: SourceDataLine: com.sun.media.sound.DirectAudioDevice$DirectSDL@f942c4
AudioLauncher: starting java audio..

但对于 user_agent_profile 使用 JMF 值是正确的,并且此代码会生成错误。

if (user_profile.audio && local_audio_port!=0 && remote_audio_port!=0)
       
         if (user_profile.use_rat)
         // create an audio_app and start it
           
            audio_app=new RATLauncher(user_profile.bin_rat,local_audio_port,remote_media_address,remote_audio_port,log);
         
         else if (user_profile.use_jmf)
          
            // check if JMF is supported
            try
              
                Class myclass=Class.forName("local.ua.JMFAudioLauncher");
                Class[] parameter_types= Class.forName("int"), Class.forName("java.lang.String"),Class.forName("int"), Class.forName("int"), Class.forName("org.zoolu.tools.Log") ;
                Object[] parameters= new Integer(local_audio_port), remote_media_address, new Integer(remote_audio_port), new Integer(dir), log ;
                java.lang.reflect.Constructor constructor=myclass.getConstructor(parameter_types);
                audio_app=(MediaLauncher)constructor.newInstance(parameters);

            
            catch (Exception e)
              
                printException(e,LogLevel.HIGH);
                printLog("Error trying to create the JMFAudioLauncher",LogLevel.HIGH);
            
        
        // else
        if (audio_app==null)
          
            // for testing..
            String audio_in=null;
            if (user_profile.send_tone) audio_in=JAudioLauncher.TONE;
            else if (user_profile.send_file!=null) audio_in=user_profile.send_file;
            String audio_out=null;
            if (user_profile.recv_file!=null) audio_out=user_profile.recv_file;        

            //audio_app=new JAudioLauncher(local_audio_port,remote_media_address,remote_audio_port,dir,log);
            audio_app=new JAudioLauncher(local_audio_port,remote_media_address,remote_audio_port,dir,audio_in,audio_out,user_profile.audio_sample_rate,user_profile.audio_sample_size,user_profile.audio_frame_size,log);
        
        audio_app.startMedia();
    

我可以做些什么来启用 JMF?

【问题讨论】:

您可能想要修复代码的缩进。你可以看到它的样子。修复它至少会使它更具可读性。 @Bart:我改进了一些格式,实际上你为什么说我的代码不可读?给我关于改进格式的具体建议。谢谢 @Alvi_1987 看看你现在有没有更多的运气。 @Alvi_1987 我已经为你修正了缩进。看看差异,看看我在说什么。这揭示了您在第二个代码块的末尾还有额外的两行,顶部没有匹配的左大括号。那些线应该在那里吗?顶部有什么遗漏吗? @Bart - 我已经添加了缺失的行。 【参考方案1】:

能否请您花点时间找出这部分代码的错误发生在哪一行?

// check if JMF is supported
try  
    Class myclass=Class.forName("local.ua.JMFAudioLauncher");
    Class[] parameter_types= Class.forName("int"), Class.forName("java.lang.String"),Class.forName("int"), Class.forName("int"), Class.forName("org.zoolu.tools.Log") ;
    Object[] parameters= new Integer(local_audio_port), remote_media_address, new Integer(remote_audio_port), new Integer(dir), log ;
    java.lang.reflect.Constructor constructor=myclass.getConstructor(parameter_types);
    audio_app=(MediaLauncher)constructor.newInstance(parameters);
    
catch (Exception e)  
    printException(e,LogLevel.HIGH);
    printLog("Error trying to create the JMFAudioLauncher",LogLevel.HIGH);
    

【讨论】:

仅作为 q/a 的参考,meta 上有一个关于该问题的问题,我当时添加了一些赏金,并放置了试图提供帮助的答案。这是元问题:meta.stackexchange.com/questions/122809/…

以上是关于为啥 JMF 不使用 Mjsip 处理音频流?的主要内容,如果未能解决你的问题,请参考以下文章

为啥将音频流添加到 ffmpeg 的 libavcodec 输出容器会导致崩溃?

为啥我在 iOS 9 上的 WKWebView 中的音频流无法播放?

为啥缓冲区大小会影响音频数据?

如何处理音频字节以从实时音频流中提取 MFCC?

LabVIEW中的音频处理(流处理可能吗??)

Android 9 Audio系统笔记:AudioFlinger音频流处理流程