Unable to Access Raw Audio Stream with Meeting SDK on Mac OS

Meeting SDK Type and Version

Zoom Meeting SDK (MacOS) v5.14.5.17739
Codebase: Objective C (building on top of ZoomSDKSample Project)

Description

Code Setup

We are trying to fetch the raw audio stream in a Mac app using Meeting SDK.

As per the documentation on raw data, here’s the sequence of operation for getting a raw audio stream:

Pre-Setup

  1. Get a local recording token for the meeting, and initialize and set the value of appPrivilegeToken for the meeting joining params.
  2. Implement an instance of ZoomSDKAudioRawDataDelegate and implement callbacks for onMixedAudioRawDataReceived and onOneWayAudioRawDataReceived.

After the Bot Joins the Meeting

  1. Call startRawRecording method, on the instance of ZoomSDKMeetingRecordController extracted from ZoomSDK.sharedSDK.getMeetingService.getRecordController
  2. Create a instance of ZoomSDKAudioRawDataHelper and pass it to getAudioRawDataHelper for managing subscription.
  3. Call subscribe method on the instance of ZoomSDKAudioRawDataHelper to subscribe to the updates happening in stream.

Issue

Even though all the calls mentioned in the steps above result in ZoomSDKError_Success, the audio stream callbacks functions are never called. Log statements written within the functions onMixedAudioRawDataReceived and onOneWayAudioRawDataReceived never appear on the terminal.

Meanwhile the app works, we can interact with it, and perform all operations, however the audio stream data is not there.

A few interesting logs that we observed are:

2023-04-27 15:26:14.878934+0530 ZoomSDKSample_universal[96051:5306020] [default] CGSWindowShmemCreateWithPort failed on port 0

2023-04-27 15:26:14.993745+0530 ZoomSDKSample_universal[96051:5306020] Detected potentially harmful notification post rate of 108.278 notifications per second

Troubleshooting Routes
We searched for this in Zook Developer Forum, StackOverflow and Apple Developer forum, but couldn’t find a reason/solution to this.

Reference Code

We have taken the sample codebase included with zoom SDK as the base codebase, and are playing around with it. Its in Objective C.

ZMSDKRawLocalRecordingStream.h

@class ZoomSDKAudioRawDataDelegate;

@interface ZMSDKRawLocalRecordingStream : NSObject <ZoomSDKAudioRawDataDelegate>

- (ZoomSDKError) subscribeToAudioStream;

@end

ZMSDKRawLocalRecordingStream.m

@interface ZMSDKRawLocalRecordingStream()
{
    ZoomSDKMeetingRecordController* meetingRecordController;
    ZoomSDKRawDataController* rawDataController;
    ZoomSDKAudioRawDataHelper* rawDataHelper;
}
@end

@implementation ZMSDKRawLocalRecordingStream

static ZMSDKRawLocalRecordingStream* recordingDelegateMgr = nil;
- (id)init {
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^{
        if (recordingDelegateMgr) {
            rawDataController = [[ZoomSDK sharedSDK] getRawDataController];
            meetingRecordController = [[[ZoomSDK sharedSDK] getMeetingService] getRecordController];
        }
    });
    
    return recordingDelegateMgr;
}

- (ZoomSDKError) subscribeToAudioStream {
    ZoomSDKAudioRawDataHelper* localRawDataHelper = [[ZoomSDKAudioRawDataHelper alloc] init];
    
    ZoomSDKError isRawRecordingStarted = [meetingRecordController startRawRecording];
    localRawDataHelper.delegate = self;
    ZoomSDKError rawDataHelperAssignment = [rawDataController getAudioRawDataHelper:&localRawDataHelper];
    ZoomSDKError rawDataHelperSubscription = [localRawDataHelper subscribe];
    
    rawDataHelper = localRawDataHelper;
    return rawDataHelperSubscription;
}

- (void)dealloc {
    [meetingRecordController stopRawRecording];
    [rawDataHelper unSubscribe];
}

- (void)onMixedAudioRawDataReceived:(ZoomSDKAudioRawData *)data {
    NSLog(@"ZMSDKRawLocalRecordingStream: onMixedAudioRawDataReceived, bufferLength %d", data.getBufferLen);
}

- (void)onOneWayAudioRawDataReceived:(ZoomSDKAudioRawData *)data nodeID:(unsigned int)nodeID {
    NSLog(@"ZMSDKRawLocalRecordingStream: onOneWayAudioRawDataReceived, bufferLength %d", data.getBufferLen);
}

@end

The subscribeToAudioStream method is called when the meeting status changes to ZoomSDKMeetingStatus_InMeeting.

I have also checked for the license using hasRawDataLicense which can be accessed through the instance of ZoomSDKRawDataController. This always returns ZoomSDKError_Success - so this should also not be a blocker for getting the audio stream.

1 Like

@sumeetsd Hope you will be fine.

Please dm me here so that we can discuss more. Thanks

@sumeetsd, It might be worth checking out Recall.ai that has a hosted solution of this so it’s just a simple API call to create a meeting bot - instead of you needing to run the Mac OS SDK at scale.