【问题标题】:Jitsi - Playing a WAV file during call - If possible, mix with audioJitsi - 在通话期间播放 WAV 文件 - 如果可能,与音频混合
【发布时间】:2014-05-04 13:57:44
【问题描述】:

我正在自定义 Jitsi 以在通话进行时播放 Wav 文件。

我在做这件事时遇到了麻烦,如果你能帮助我,我将不胜感激。

我可以在通话开始前切换数据源,方法是使用自定义 AudioFileMediaDevice 并在 CallPeerMediaHandler 中将其打开。

但是当调用正在进行时,我在替换数据源时遇到了问题。

================================================ ===============

我尝试了以下方法,但无法正常工作。

1) 我尝试获取设备的输出数据源,并使用 addInDataSource 方法添加了 wav 文件的 URLDatasource。没用。

DataSource dataSource = device.createOutputDataSource();

DataSource fileDataSource = Manager.createDataSource(new URL("file://resources/sounds/Sample.wav"));
((AudioMixingPushBufferDataSource)dataSource).addInDataSource(fileDataSource);

2) 我尝试添加自定义捕获设备并切换它,但它也不起作用:

CaptureDeviceInfo2 fileDevice =
                new CaptureDeviceInfo2("Recorded Audio 1",
                    fileDataSource.getLocator(), null, null, null, null);

            ((MediaServiceImpl) LibJitsi.getMediaService())
                .getDeviceConfiguration().getAudioSystem().setDevice(AudioSystem.DataFlow.CAPTURE, fileDevice, false);

这只是用于播放,而不是作为捕获设备。

3) 我什至尝试添加一个新的音频系统,将播放设备作为文件数据源,但这也不起作用。

================================================ ===============

我是 libjitsi 的新手,所以我很难尝试解码正在发生的事情。 任何有关如何解决此问题的说明都会很棒。

【问题讨论】:

  • 你解决了这个任务吗?我试图做同样的事情并陷入困境。
  • 如果您要查找的内容也可以通过从普通 java 播放 .WAV 文件来解决,请告诉我。

标签: java file audio device jitsi


【解决方案1】:

我用这段代码在通话中播放了声音:

public void startPlaying(CallPeer callPeer, DataSource soundDataSource) throws OperationFailedException {
    assert callPeer instanceof CallPeerSipImpl;
    CallPeerSipImpl cp = (CallPeerSipImpl) callPeer;
    AudioMediaStreamImpl audioMediaStream = (AudioMediaStreamImpl) cp.getMediaHandler().getStream(MediaType.AUDIO);
    AudioMediaDeviceSession deviceSession = audioMediaStream.getDeviceSession();
    assert deviceSession != null;
    assert deviceSession.getDevice() instanceof AudioMixerMediaDevice;
    AudioMixerMediaDevice dev = (AudioMixerMediaDevice) deviceSession.getDevice();
    dev.getAudioMixer().addInDataSource(soundDataSource);
}

请注意,AudioMixerMediaDevice.getAudioMixer() 在 libjitsi 中具有私有访问权限,因此我将其公开并重新编译。

【讨论】:

    【解决方案2】:

    我需要在通话期间播放音频文件,但只能在通话的远端播放。所以我用 stoktos 的例子玩了一下,并根据我的需要对其进行了修改。如果有人需要它,这就是我所做的:

    private void playAudioFromDataSource(final CallPeerSipImpl callPeer, final DataSource audioDataSource, final MediaDirection direction) {
        final CallPeerMediaHandlerSipImpl mediaHandler = callPeer.getMediaHandler();
        final AudioMediaStreamImpl audioMediaStream = (AudioMediaStreamImpl) mediaHandler.getStream(AUDIO);
        final AudioMediaDeviceSession deviceSession = audioMediaStream.getDeviceSession();
        if (null != deviceSession) {
            if (RECVONLY == direction) {
                // plays audio local only:
                deviceSession.addPlaybackDataSource(audioDataSource);
            } else {
                final AudioMixerMediaDevice mediaDevice = (AudioMixerMediaDevice) deviceSession.getDevice();
                final AudioMixer audioMixer = getAudioMixer(mediaDevice);
                if (null != audioMixer) {
                    if (SENDONLY == direction) {
                        // plays audio remote only:
                        audioMixer.getLocalOutDataSource().addInDataSource(audioDataSource);
                    } else if (SENDRECV == direction) {
                        // plays audio on both sides of call (local and remote):
                        audioMixer.addInDataSource(audioDataSource);
                    }
                }
            }
        }
    }
    
    private AudioMixer getAudioMixer(final AudioMixerMediaDevice device) {
        try {
            final Method privateGetAudioMixerMethod = device.getClass().getDeclaredMethod("getAudioMixer");
            privateGetAudioMixerMethod.setAccessible(true);
            final Object audioMixerObject = privateGetAudioMixerMethod.invoke(device, (Object[]) null);
            return (AudioMixer) audioMixerObject;
        } catch (final Exception e) {
            log.error("Could not get AudioMixer", e);
        }
        return null;
    }
    

    注意:我使用反射来获取私有 AudioMixer 对象。我承认这不是最干净的方法,但它有效。 :)

    【讨论】:

      猜你喜欢
      • 2017-11-16
      • 1970-01-01
      • 1970-01-01
      • 2019-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多