Skip to content

Commit

Permalink
[APPS-533] Pipe audio
Browse files Browse the repository at this point in the history
  • Loading branch information
katelyn-gallagher authored and Gandri committed Apr 29, 2024
1 parent 32348af commit ba5e404
Show file tree
Hide file tree
Showing 4 changed files with 270 additions and 74 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.oney.WebRTCModule;

import android.annotation.SuppressLint;

import org.webrtc.audio.JavaAudioDeviceModule.SamplesReadyCallback;
import org.webrtc.audio.JavaAudioDeviceModule.AudioSamples;

import java.util.HashMap;

// Note: This is a happy path implementation and heavily based off of Flutters webrtc implementation
// https://github.com/flutter-webrtc/flutter-webrtc/blob/main/android/src/main/java/com/cloudwebrtc/webrtc/record/AudioSamplesInterceptor.java

/** JavaAudioDeviceModule allows attaching samples callback only on building
* We don't want to instantiate VideoFileRenderer and codecs at this step
* It's simple dummy class, it does nothing until samples are necessary */
@SuppressWarnings("WeakerAccess")
public class AudioSamplesInterceptor implements SamplesReadyCallback {

@SuppressLint("UseSparseArrays")
protected final HashMap<String, SamplesReadyCallback> callbacks = new HashMap<>();

@Override
public void onWebRtcAudioRecordSamplesReady(AudioSamples audioSamples) {
for (SamplesReadyCallback callback : callbacks.values()) {
callback.onWebRtcAudioRecordSamplesReady(audioSamples);
}
}

public void attachCallback(String id, SamplesReadyCallback callback) throws Exception {
callbacks.put(id, callback);
}

public void detachCallback(String id) {
callbacks.remove(id);
}

}
20 changes: 16 additions & 4 deletions android/src/main/java/com/oney/WebRTCModule/MediaRecorderImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class MediaRecorderImpl {
private final VideoTrack videoTrack;
private final HashMap videoTrackInfo;
private File file;
private AudioSamplesInterceptor audioSamplesInterceptor;

/**
* VideoAudioFileRenderer is heavily influenced by Flutter's webRTC implementation
Expand All @@ -24,12 +25,19 @@ public class MediaRecorderImpl {
*
* @param id Id
* @param videoTrack Video track
* @param videoTrackInfo Necessary video track info, like frame rate
* @param interceptor Eventually we'll add this param as an AudioSamplesInterceptor to pipe audio
*/
protected MediaRecorderImpl(String id, VideoTrack videoTrack, HashMap<String, Integer> videoTrackInfo) {
protected MediaRecorderImpl(
String id,
VideoTrack videoTrack,
HashMap<String, Integer> videoTrackInfo,
AudioSamplesInterceptor interceptor
) {
this.id = id;
this.videoTrack = videoTrack;
this.videoTrackInfo = videoTrackInfo;
this.audioSamplesInterceptor = interceptor;
}

protected void start(File file) throws Exception {
Expand All @@ -50,15 +58,19 @@ protected void start(File file) throws Exception {
videoTrackInfo
);
videoTrack.addSink(videoAudioFileRenderer);
audioSamplesInterceptor.attachCallback(id, videoAudioFileRenderer);

Log.i(TAG, "Started media recorder! " + videoAudioFileRenderer.toString());
}
}

protected File stop() {
// Remove sink from videoTrack (https://chromium.googlesource.com/external/webrtc/+/HEAD/sdk/android/api/org/webrtc/VideoTrack.java#49)
// Release videoAudioFileRenderer, and set to null
videoTrack.removeSink(videoAudioFileRenderer);
videoAudioFileRenderer.release();
videoAudioFileRenderer = null;

return file;
audioSamplesInterceptor.detachCallback(id);

return file;
}
}
Loading

0 comments on commit ba5e404

Please sign in to comment.