react-native-audio-api 0.10.0-nightly-c815c40-20251026 → 0.11.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/RNAudioAPI.podspec +5 -9
- package/android/build.gradle +3 -33
- package/android/src/main/cpp/audioapi/android/AudioAPIModule.cpp +0 -5
- package/android/src/main/cpp/audioapi/android/AudioAPIModule.h +0 -1
- package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.cpp +94 -28
- package/android/src/main/cpp/audioapi/android/core/AndroidAudioRecorder.h +28 -14
- package/android/src/main/cpp/audioapi/android/core/AudioPlayer.cpp +2 -4
- package/android/src/main/cpp/audioapi/android/core/NativeAudioRecorder.hpp +9 -9
- package/android/src/main/cpp/audioapi/android/core/utils/AndroidFileWriterBackend.h +33 -0
- package/android/src/main/cpp/audioapi/android/core/utils/AudioDecoder.cpp +0 -6
- package/android/src/main/cpp/audioapi/android/core/utils/FileUtils.h +34 -0
- package/android/src/main/cpp/audioapi/android/core/utils/FileUtilts.cpp +133 -0
- package/android/src/main/cpp/audioapi/android/core/utils/MiniaudioImplementation.cpp +3 -0
- package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegAudioFileOptions.cpp +154 -0
- package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegAudioFileOptions.h +41 -0
- package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegFileWriter.cpp +431 -0
- package/android/src/main/cpp/audioapi/android/core/utils/ffmpegBackend/FFmpegFileWriter.h +112 -0
- package/android/src/main/cpp/audioapi/android/core/utils/miniaudioBackend/MiniAudioFileOptions.cpp +47 -0
- package/android/src/main/cpp/audioapi/android/core/utils/miniaudioBackend/MiniAudioFileOptions.h +28 -0
- package/android/src/main/cpp/audioapi/android/core/utils/miniaudioBackend/MiniAudioFileWriter.cpp +237 -0
- package/android/src/main/cpp/audioapi/android/core/utils/miniaudioBackend/MiniAudioFileWriter.h +46 -0
- package/android/src/main/cpp/audioapi/android/system/NativeFileInfo.hpp +31 -0
- package/android/src/main/java/com/swmansion/audioapi/AudioAPIModule.kt +3 -29
- package/android/src/main/java/com/swmansion/audioapi/system/AudioFocusListener.kt +9 -21
- package/android/src/main/java/com/swmansion/audioapi/system/NativeFileInfo.kt +18 -0
- package/android/src/main/jniLibs/arm64-v8a/libavcodec.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libavformat.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libavutil.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libswresample.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libavcodec.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libavformat.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libavutil.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libswresample.so +0 -0
- package/android/src/main/jniLibs/x86/libavcodec.so +0 -0
- package/android/src/main/jniLibs/x86/libavformat.so +0 -0
- package/android/src/main/jniLibs/x86/libavutil.so +0 -0
- package/android/src/main/jniLibs/x86/libswresample.so +0 -0
- package/android/src/main/jniLibs/x86_64/libavcodec.so +0 -0
- package/android/src/main/jniLibs/x86_64/libavformat.so +0 -0
- package/android/src/main/jniLibs/x86_64/libavutil.so +0 -0
- package/android/src/main/jniLibs/x86_64/libswresample.so +0 -0
- package/common/cpp/audioapi/AudioAPIModuleInstaller.h +2 -30
- package/common/cpp/audioapi/HostObjects/effects/BiquadFilterNodeHostObject.cpp +1 -1
- package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.cpp +80 -18
- package/common/cpp/audioapi/HostObjects/inputs/AudioRecorderHostObject.h +15 -6
- package/common/cpp/audioapi/core/AudioParam.cpp +2 -2
- package/common/cpp/audioapi/core/effects/BiquadFilterNode.cpp +32 -69
- package/common/cpp/audioapi/core/effects/BiquadFilterNode.h +1 -37
- package/common/cpp/audioapi/core/inputs/AudioRecorder.cpp +102 -49
- package/common/cpp/audioapi/core/inputs/AudioRecorder.h +46 -28
- package/common/cpp/audioapi/core/utils/Constants.h +1 -2
- package/common/cpp/audioapi/core/utils/worklets/SafeIncludes.h +10 -0
- package/common/cpp/audioapi/external/arm64-v8a/libcrypto.a +0 -0
- package/common/cpp/audioapi/external/arm64-v8a/libogg.a +0 -0
- package/common/cpp/audioapi/external/arm64-v8a/libopus.a +0 -0
- package/common/cpp/audioapi/external/arm64-v8a/libopusfile.a +0 -0
- package/common/cpp/audioapi/external/arm64-v8a/libssl.a +0 -0
- package/common/cpp/audioapi/external/arm64-v8a/libvorbis.a +0 -0
- package/common/cpp/audioapi/external/arm64-v8a/libvorbisenc.a +0 -0
- package/common/cpp/audioapi/external/arm64-v8a/libvorbisfile.a +0 -0
- package/common/cpp/audioapi/external/armeabi-v7a/libcrypto.a +0 -0
- package/common/cpp/audioapi/external/armeabi-v7a/libogg.a +0 -0
- package/common/cpp/audioapi/external/armeabi-v7a/libopus.a +0 -0
- package/common/cpp/audioapi/external/armeabi-v7a/libopusfile.a +0 -0
- package/common/cpp/audioapi/external/armeabi-v7a/libssl.a +0 -0
- package/common/cpp/audioapi/external/armeabi-v7a/libvorbis.a +0 -0
- package/common/cpp/audioapi/external/armeabi-v7a/libvorbisenc.a +0 -0
- package/common/cpp/audioapi/external/armeabi-v7a/libvorbisfile.a +0 -0
- package/common/cpp/audioapi/external/ffmpeg_include/libavcodec/avcodec.h +2 -2
- package/common/cpp/audioapi/external/ffmpeg_include/libavcodec/codec.h +1 -1
- package/common/cpp/audioapi/external/ffmpeg_include/libavcodec/codec_desc.h +1 -1
- package/common/cpp/audioapi/external/ffmpeg_include/libavcodec/codec_id.h +1 -1
- package/common/cpp/audioapi/external/ffmpeg_include/libavcodec/codec_par.h +1 -1
- package/common/cpp/audioapi/external/ffmpeg_include/libavformat/avformat.h +2 -2
- package/common/cpp/audioapi/external/ffmpeg_include/libavutil/avutil.h +2 -2
- package/common/cpp/audioapi/external/iphoneos/libcrypto.a +0 -0
- package/common/cpp/audioapi/external/iphoneos/libogg.a +0 -0
- package/common/cpp/audioapi/external/iphoneos/libopus.a +0 -0
- package/common/cpp/audioapi/external/iphoneos/libopusfile.a +0 -0
- package/common/cpp/audioapi/external/iphoneos/libssl.a +0 -0
- package/common/cpp/audioapi/external/iphoneos/libvorbis.a +0 -0
- package/common/cpp/audioapi/external/iphoneos/libvorbisenc.a +0 -0
- package/common/cpp/audioapi/external/iphoneos/libvorbisfile.a +0 -0
- package/common/cpp/audioapi/external/iphonesimulator/libcrypto.a +0 -0
- package/common/cpp/audioapi/external/iphonesimulator/libogg.a +0 -0
- package/common/cpp/audioapi/external/iphonesimulator/libopus.a +0 -0
- package/common/cpp/audioapi/external/iphonesimulator/libopusfile.a +0 -0
- package/common/cpp/audioapi/external/iphonesimulator/libssl.a +0 -0
- package/common/cpp/audioapi/external/iphonesimulator/libvorbis.a +0 -0
- package/common/cpp/audioapi/external/iphonesimulator/libvorbisenc.a +0 -0
- package/common/cpp/audioapi/external/iphonesimulator/libvorbisfile.a +0 -0
- package/common/cpp/audioapi/external/libavcodec.xcframework/Info.plist +44 -0
- package/common/cpp/audioapi/external/libavcodec.xcframework/ios-arm64/libavcodec.framework/Info.plist +1 -0
- package/common/cpp/audioapi/external/libavcodec.xcframework/ios-arm64/libavcodec.framework/libavcodec +0 -0
- package/common/cpp/audioapi/external/libavcodec.xcframework/ios-arm64_x86_64-simulator/libavcodec.framework/Info.plist +1 -0
- package/common/cpp/audioapi/external/libavcodec.xcframework/ios-arm64_x86_64-simulator/libavcodec.framework/libavcodec +0 -0
- package/common/cpp/audioapi/external/libavformat.xcframework/Info.plist +44 -0
- package/common/cpp/audioapi/external/libavformat.xcframework/ios-arm64/libavformat.framework/Info.plist +1 -0
- package/common/cpp/audioapi/external/libavformat.xcframework/ios-arm64/libavformat.framework/libavformat +0 -0
- package/common/cpp/audioapi/external/libavformat.xcframework/ios-arm64_x86_64-simulator/libavformat.framework/Info.plist +1 -0
- package/common/cpp/audioapi/external/libavformat.xcframework/ios-arm64_x86_64-simulator/libavformat.framework/libavformat +0 -0
- package/common/cpp/audioapi/external/libavutil.xcframework/Info.plist +44 -0
- package/common/cpp/audioapi/external/libavutil.xcframework/ios-arm64/libavutil.framework/Info.plist +1 -0
- package/common/cpp/audioapi/external/libavutil.xcframework/ios-arm64/libavutil.framework/libavutil +0 -0
- package/common/cpp/audioapi/external/libavutil.xcframework/ios-arm64_x86_64-simulator/libavutil.framework/Info.plist +1 -0
- package/common/cpp/audioapi/external/libavutil.xcframework/ios-arm64_x86_64-simulator/libavutil.framework/libavutil +0 -0
- package/common/cpp/audioapi/external/libswresample.xcframework/Info.plist +44 -0
- package/common/cpp/audioapi/external/libswresample.xcframework/ios-arm64/libswresample.framework/Info.plist +1 -0
- package/common/cpp/audioapi/external/libswresample.xcframework/ios-arm64/libswresample.framework/libswresample +0 -0
- package/common/cpp/audioapi/external/libswresample.xcframework/ios-arm64_x86_64-simulator/libswresample.framework/Info.plist +1 -0
- package/common/cpp/audioapi/external/libswresample.xcframework/ios-arm64_x86_64-simulator/libswresample.framework/libswresample +0 -0
- package/common/cpp/audioapi/external/x86/libcrypto.a +0 -0
- package/common/cpp/audioapi/external/x86/libogg.a +0 -0
- package/common/cpp/audioapi/external/x86/libopus.a +0 -0
- package/common/cpp/audioapi/external/x86/libopusfile.a +0 -0
- package/common/cpp/audioapi/external/x86/libssl.a +0 -0
- package/common/cpp/audioapi/external/x86/libvorbis.a +0 -0
- package/common/cpp/audioapi/external/x86/libvorbisenc.a +0 -0
- package/common/cpp/audioapi/external/x86/libvorbisfile.a +0 -0
- package/common/cpp/audioapi/external/x86_64/libcrypto.a +0 -0
- package/common/cpp/audioapi/external/x86_64/libogg.a +0 -0
- package/common/cpp/audioapi/external/x86_64/libopus.a +0 -0
- package/common/cpp/audioapi/external/x86_64/libopusfile.a +0 -0
- package/common/cpp/audioapi/external/x86_64/libssl.a +0 -0
- package/common/cpp/audioapi/external/x86_64/libvorbis.a +0 -0
- package/common/cpp/audioapi/external/x86_64/libvorbisenc.a +0 -0
- package/common/cpp/audioapi/external/x86_64/libvorbisfile.a +0 -0
- package/common/cpp/audioapi/libs/ffmpeg/FFmpegDecoding.cpp +3 -2
- package/common/cpp/audioapi/libs/ffmpeg/INSTRUCTIONS.md +32 -0
- package/common/cpp/audioapi/libs/ffmpeg/create_xcframework.sh +111 -0
- package/common/cpp/audioapi/libs/ffmpeg/ffmpeg_setup.sh +391 -0
- package/common/cpp/test/CMakeLists.txt +0 -3
- package/ios/audioapi/ios/AudioAPIModule.h +1 -2
- package/ios/audioapi/ios/AudioAPIModule.mm +0 -2
- package/ios/audioapi/ios/core/IOSAudioFileOptions.h +35 -0
- package/ios/audioapi/ios/core/IOSAudioFileOptions.mm +135 -0
- package/ios/audioapi/ios/core/IOSAudioFileWriter.h +38 -0
- package/ios/audioapi/ios/core/IOSAudioFileWriter.mm +187 -0
- package/ios/audioapi/ios/core/IOSAudioRecorder.h +18 -10
- package/ios/audioapi/ios/core/IOSAudioRecorder.mm +70 -28
- package/ios/audioapi/ios/core/NativeAudioRecorder.h +2 -6
- package/ios/audioapi/ios/core/NativeAudioRecorder.m +5 -73
- package/ios/audioapi/ios/system/AudioEngine.mm +3 -3
- package/ios/audioapi/ios/system/AudioSessionManager.mm +0 -9
- package/ios/audioapi/ios/system/LockScreenManager.h +1 -0
- package/ios/audioapi/ios/system/LockScreenManager.mm +19 -6
- package/lib/commonjs/api.js +76 -134
- package/lib/commonjs/api.js.map +1 -1
- package/lib/commonjs/core/AudioContext.js +1 -1
- package/lib/commonjs/core/AudioContext.js.map +1 -1
- package/lib/commonjs/core/AudioRecorder.js +157 -12
- package/lib/commonjs/core/AudioRecorder.js.map +1 -1
- package/lib/commonjs/core/BaseAudioContext.js +25 -16
- package/lib/commonjs/core/BaseAudioContext.js.map +1 -1
- package/lib/commonjs/core/OfflineAudioContext.js +1 -1
- package/lib/commonjs/core/OfflineAudioContext.js.map +1 -1
- package/lib/commonjs/types.js +50 -0
- package/lib/commonjs/types.js.map +1 -1
- package/lib/commonjs/utils/bitEnums.js +33 -0
- package/lib/commonjs/utils/bitEnums.js.map +1 -0
- package/lib/commonjs/utils/index.js +21 -19
- package/lib/commonjs/utils/index.js.map +1 -1
- package/lib/module/api.js +15 -15
- package/lib/module/api.js.map +1 -1
- package/lib/module/core/AudioContext.js +2 -2
- package/lib/module/core/AudioContext.js.map +1 -1
- package/lib/module/core/AudioRecorder.js +157 -12
- package/lib/module/core/AudioRecorder.js.map +1 -1
- package/lib/module/core/BaseAudioContext.js +26 -17
- package/lib/module/core/BaseAudioContext.js.map +1 -1
- package/lib/module/core/OfflineAudioContext.js +2 -2
- package/lib/module/core/OfflineAudioContext.js.map +1 -1
- package/lib/module/types.js +46 -0
- package/lib/module/types.js.map +1 -1
- package/lib/module/utils/bitEnums.js +27 -0
- package/lib/module/utils/bitEnums.js.map +1 -0
- package/lib/module/utils/index.js +2 -15
- package/lib/module/utils/index.js.map +1 -1
- package/lib/typescript/api.d.ts +17 -18
- package/lib/typescript/api.d.ts.map +1 -1
- package/lib/typescript/core/AudioContext.d.ts.map +1 -1
- package/lib/typescript/core/AudioRecorder.d.ts +58 -6
- package/lib/typescript/core/AudioRecorder.d.ts.map +1 -1
- package/lib/typescript/core/BaseAudioContext.d.ts.map +1 -1
- package/lib/typescript/events/types.d.ts +16 -0
- package/lib/typescript/events/types.d.ts.map +1 -1
- package/lib/typescript/interfaces.d.ts +39 -3
- package/lib/typescript/interfaces.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +75 -4
- package/lib/typescript/types.d.ts.map +1 -1
- package/lib/typescript/utils/bitEnums.d.ts +4 -0
- package/lib/typescript/utils/bitEnums.d.ts.map +1 -0
- package/lib/typescript/utils/index.d.ts +2 -5
- package/lib/typescript/utils/index.d.ts.map +1 -1
- package/package.json +4 -7
- package/src/api.ts +18 -44
- package/src/core/AudioContext.ts +2 -3
- package/src/core/AudioRecorder.ts +190 -20
- package/src/core/BaseAudioContext.ts +60 -44
- package/src/core/OfflineAudioContext.ts +2 -2
- package/src/events/types.ts +18 -0
- package/src/interfaces.ts +47 -4
- package/src/types.ts +86 -4
- package/src/utils/bitEnums.ts +51 -0
- package/src/utils/index.ts +2 -22
- package/common/cpp/audioapi/libs/ffmpeg/relinking.md +0 -24
- package/common/cpp/test/src/biquad/BiquadFilterChromium.cpp +0 -389
- package/common/cpp/test/src/biquad/BiquadFilterChromium.h +0 -64
- package/common/cpp/test/src/biquad/BiquadFilterTest.cpp +0 -284
- package/common/cpp/test/src/biquad/BiquadFilterTest.h +0 -40
- package/scripts/download-prebuilt-binaries.sh +0 -52
- package/scripts/rnaa_utils.rb +0 -8
- package/scripts/validate-worklets-version.js +0 -28
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
#import <AVFoundation/AVFoundation.h>
|
|
2
|
+
#import <Foundation/Foundation.h>
|
|
3
|
+
|
|
4
|
+
#include <audioapi/ios/core/IOSAudioFileOptions.h>
|
|
5
|
+
#include <audioapi/ios/core/IOSAudioFileWriter.h>
|
|
6
|
+
|
|
7
|
+
namespace audioapi {
|
|
8
|
+
IOSAudioFileWriter::IOSAudioFileWriter(float sampleRate, size_t channelCount, size_t bitRate, size_t iosFlags)
|
|
9
|
+
{
|
|
10
|
+
fileOptions_ = std::make_shared<IOSAudioFileOptions>(sampleRate, channelCount, bitRate, iosFlags);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
IOSAudioFileWriter::~IOSAudioFileWriter()
|
|
14
|
+
{
|
|
15
|
+
fileURL_ = nil;
|
|
16
|
+
audioFile_ = nil;
|
|
17
|
+
converter_ = nil;
|
|
18
|
+
bufferFormat_ = nil;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
void IOSAudioFileWriter::openFile(AVAudioFormat *bufferFormat)
|
|
22
|
+
{
|
|
23
|
+
@autoreleasepool {
|
|
24
|
+
if (audioFile_ != nil) {
|
|
25
|
+
NSLog(@"⚠️ createFileForWriting: currentAudioFile_ already exists");
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
bufferFormat_ = bufferFormat;
|
|
30
|
+
|
|
31
|
+
NSError *error = nil;
|
|
32
|
+
NSDictionary *settings = fileOptions_->getFileSettings();
|
|
33
|
+
fileURL_ = getFileURL();
|
|
34
|
+
|
|
35
|
+
NSLog(@"ℹ️ Creating audio file at URL: %@", [fileURL_ absoluteString]);
|
|
36
|
+
|
|
37
|
+
audioFile_ = [[AVAudioFile alloc] initForWriting:fileURL_
|
|
38
|
+
settings:settings
|
|
39
|
+
commonFormat:AVAudioPCMFormatFloat32
|
|
40
|
+
interleaved:bufferFormat.interleaved
|
|
41
|
+
error:&error];
|
|
42
|
+
converter_ = [[AVAudioConverter alloc] initFromFormat:bufferFormat toFormat:[audioFile_ processingFormat]];
|
|
43
|
+
converter_.sampleRateConverterAlgorithm = AVSampleRateConverterAlgorithm_Normal;
|
|
44
|
+
converter_.sampleRateConverterQuality = AVAudioQualityMax;
|
|
45
|
+
converter_.primeMethod = AVAudioConverterPrimeMethod_None;
|
|
46
|
+
|
|
47
|
+
NSLog(@"buferFormat: %@ fileFormat: %@", bufferFormat, [audioFile_ processingFormat]);
|
|
48
|
+
|
|
49
|
+
if (error != nil || audioFile_ == nil) {
|
|
50
|
+
NSLog(@"Error creating audio file for writing: %@", [error debugDescription]);
|
|
51
|
+
audioFile_ = nil;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
std::string IOSAudioFileWriter::closeFile()
|
|
57
|
+
{
|
|
58
|
+
@autoreleasepool {
|
|
59
|
+
std::string filePath = [[fileURL_ path] UTF8String];
|
|
60
|
+
|
|
61
|
+
if (audioFile_ == nil) {
|
|
62
|
+
return "";
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// AVAudioFile automatically finalizes the file when deallocated
|
|
66
|
+
audioFile_ = nil;
|
|
67
|
+
fileURL_ = nil;
|
|
68
|
+
return filePath;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
bool IOSAudioFileWriter::writeAudioData(const AudioBufferList *audioBufferList, int numFrames)
|
|
73
|
+
{
|
|
74
|
+
if (audioFile_ == nil) {
|
|
75
|
+
NSLog(@"⚠️ writeAudioData: audioFile is nil, cannot write data");
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// TODO: not sure if this is necessary
|
|
80
|
+
@autoreleasepool {
|
|
81
|
+
NSError *error = nil;
|
|
82
|
+
AVAudioFormat *filePCMFormat = [audioFile_ processingFormat];
|
|
83
|
+
|
|
84
|
+
if (audioBufferList->mNumberBuffers != filePCMFormat.channelCount ||
|
|
85
|
+
bufferFormat_.sampleRate != filePCMFormat.sampleRate ||
|
|
86
|
+
bufferFormat_.interleaved != filePCMFormat.interleaved) {
|
|
87
|
+
int outputFrameCount = ceil(numFrames * filePCMFormat.sampleRate / bufferFormat_.sampleRate);
|
|
88
|
+
|
|
89
|
+
AVAudioPCMBuffer *inputBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:bufferFormat_
|
|
90
|
+
frameCapacity:(AVAudioFrameCount)numFrames];
|
|
91
|
+
|
|
92
|
+
for (int i = 0; i < bufferFormat_.channelCount; i++) {
|
|
93
|
+
memcpy(
|
|
94
|
+
inputBuffer.mutableAudioBufferList->mBuffers[i].mData,
|
|
95
|
+
audioBufferList->mBuffers[i].mData,
|
|
96
|
+
audioBufferList->mBuffers[i].mDataByteSize);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
inputBuffer.frameLength = numFrames;
|
|
100
|
+
AVAudioPCMBuffer *outputBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:filePCMFormat
|
|
101
|
+
frameCapacity:outputFrameCount];
|
|
102
|
+
outputBuffer.frameLength = outputFrameCount;
|
|
103
|
+
|
|
104
|
+
AVAudioConverterInputBlock inputBlock =
|
|
105
|
+
^AVAudioBuffer *_Nullable(AVAudioPacketCount inNumberOfPackets, AVAudioConverterInputStatus *outStatus)
|
|
106
|
+
{
|
|
107
|
+
// this line is probably an delusion, but for my sanity lets keep it
|
|
108
|
+
inNumberOfPackets = numFrames;
|
|
109
|
+
*outStatus = AVAudioConverterInputStatus_HaveData;
|
|
110
|
+
return inputBuffer;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
[converter_ convertToBuffer:outputBuffer error:&error withInputFromBlock:inputBlock];
|
|
114
|
+
|
|
115
|
+
if (error != nil) {
|
|
116
|
+
NSLog(@"Error during audio conversion: %@", [error debugDescription]);
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
[audioFile_ writeFromBuffer:outputBuffer error:&error];
|
|
121
|
+
|
|
122
|
+
if (error != nil) {
|
|
123
|
+
NSLog(@"Error writing audio data to file: %@", [error debugDescription]);
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
AVAudioPCMBuffer *processingBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:filePCMFormat
|
|
128
|
+
bufferListNoCopy:audioBufferList
|
|
129
|
+
deallocator:NULL];
|
|
130
|
+
|
|
131
|
+
[audioFile_ writeFromBuffer:processingBuffer error:&error];
|
|
132
|
+
|
|
133
|
+
if (error != nil) {
|
|
134
|
+
NSLog(@"Error writing audio data to file: %@", [error debugDescription]);
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
NSString *IOSAudioFileWriter::getISODateStringForDirectory()
|
|
144
|
+
{
|
|
145
|
+
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
|
|
146
|
+
fmt.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
|
|
147
|
+
fmt.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; // or local if you prefer
|
|
148
|
+
fmt.dateFormat = @"yyyy-MM-dd";
|
|
149
|
+
return [fmt stringFromDate:[NSDate date]];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
NSString *IOSAudioFileWriter::getTimestampForFilename()
|
|
153
|
+
{
|
|
154
|
+
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
|
|
155
|
+
fmt.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
|
|
156
|
+
fmt.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; // or local if you prefer
|
|
157
|
+
fmt.dateFormat = @"yyyyMMdd_HHmmss_SSS";
|
|
158
|
+
return [fmt stringFromDate:[NSDate date]];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
NSURL *IOSAudioFileWriter::getFileURL()
|
|
162
|
+
{
|
|
163
|
+
NSError *error = nil;
|
|
164
|
+
|
|
165
|
+
NSSearchPathDirectory searchDirectory = fileOptions_->getDirectory();
|
|
166
|
+
NSString *directory = [NSString stringWithFormat:@"AudioAPI/%@", getISODateStringForDirectory()];
|
|
167
|
+
|
|
168
|
+
NSURL *baseURL = [[[NSFileManager defaultManager] URLsForDirectory:searchDirectory
|
|
169
|
+
inDomains:NSUserDomainMask] firstObject];
|
|
170
|
+
NSURL *dirURL = [baseURL URLByAppendingPathComponent:directory isDirectory:YES];
|
|
171
|
+
|
|
172
|
+
[[NSFileManager defaultManager] createDirectoryAtURL:dirURL
|
|
173
|
+
withIntermediateDirectories:YES
|
|
174
|
+
attributes:nil
|
|
175
|
+
error:&error];
|
|
176
|
+
|
|
177
|
+
if (error != nil) {
|
|
178
|
+
NSLog(@"Error creating directory for audio recordings: %@", [error debugDescription]);
|
|
179
|
+
dirURL = baseURL;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
NSString *fileName =
|
|
183
|
+
[NSString stringWithFormat:@"audio_%@.%@", getTimestampForFilename(), fileOptions_->getFileExtension()];
|
|
184
|
+
return [dirURL URLByAppendingPathComponent:fileName];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
} // namespace audioapi
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
-
#ifdef __OBJC__ // when compiled as
|
|
3
|
+
#ifdef __OBJC__ // when compiled as C++
|
|
4
4
|
#import <NativeAudioRecorder.h>
|
|
5
|
-
#else
|
|
5
|
+
#else
|
|
6
|
+
typedef struct objc_object AVAudioFile;
|
|
7
|
+
typedef struct objc_object NSURL;
|
|
8
|
+
typedef struct objc_object AudioBufferList;
|
|
6
9
|
typedef struct objc_object NativeAudioRecorder;
|
|
7
10
|
#endif // __OBJC__
|
|
8
11
|
|
|
@@ -12,22 +15,27 @@ namespace audioapi {
|
|
|
12
15
|
|
|
13
16
|
class AudioBus;
|
|
14
17
|
class CircularAudioArray;
|
|
18
|
+
class IOSAudioFileWriter;
|
|
19
|
+
class AudioEventHandlerRegistry;
|
|
15
20
|
|
|
16
21
|
class IOSAudioRecorder : public AudioRecorder {
|
|
17
22
|
public:
|
|
18
|
-
IOSAudioRecorder(
|
|
19
|
-
float sampleRate,
|
|
20
|
-
int bufferLength,
|
|
21
|
-
const std::shared_ptr<AudioEventHandlerRegistry>
|
|
22
|
-
&audioEventHandlerRegistry);
|
|
23
|
-
|
|
23
|
+
IOSAudioRecorder(const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry);
|
|
24
24
|
~IOSAudioRecorder() override;
|
|
25
25
|
|
|
26
26
|
void start() override;
|
|
27
|
-
|
|
27
|
+
std::string stop() override;
|
|
28
|
+
|
|
29
|
+
void enableFileOutput(float sampleRate, size_t channelCount, size_t bitRate, size_t iosFlags, size_t androidFlags)
|
|
30
|
+
override;
|
|
31
|
+
void disableFileOutput() override;
|
|
32
|
+
|
|
33
|
+
void pause() override;
|
|
34
|
+
void resume() override;
|
|
28
35
|
|
|
29
36
|
private:
|
|
30
|
-
|
|
37
|
+
std::shared_ptr<IOSAudioFileWriter> fileWriter_;
|
|
38
|
+
NativeAudioRecorder *nativeRecorder_;
|
|
31
39
|
};
|
|
32
40
|
|
|
33
41
|
} // namespace audioapi
|
|
@@ -1,70 +1,112 @@
|
|
|
1
1
|
#import <AVFoundation/AVFoundation.h>
|
|
2
|
+
#import <Foundation/Foundation.h>
|
|
3
|
+
#include <unordered_map>
|
|
2
4
|
|
|
3
5
|
#include <audioapi/core/utils/Constants.h>
|
|
4
6
|
#include <audioapi/dsp/VectorMath.h>
|
|
5
7
|
#include <audioapi/events/AudioEventHandlerRegistry.h>
|
|
8
|
+
#include <audioapi/ios/core/IOSAudioFileWriter.h>
|
|
6
9
|
#include <audioapi/ios/core/IOSAudioRecorder.h>
|
|
7
10
|
#include <audioapi/utils/AudioArray.h>
|
|
8
11
|
#include <audioapi/utils/AudioBus.h>
|
|
9
12
|
#include <audioapi/utils/CircularAudioArray.h>
|
|
10
13
|
#include <audioapi/utils/CircularOverflowableAudioArray.h>
|
|
11
|
-
#include <unordered_map>
|
|
12
14
|
|
|
13
15
|
namespace audioapi {
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
writeToBuffers(inputChannel, numFrames);
|
|
25
|
-
}
|
|
17
|
+
// AudioReceiverBlock audioReceiverBlock = ^(const AudioBufferList *inputBuffer, int numFrames) {
|
|
18
|
+
// if (isRunning_.load()) {
|
|
19
|
+
// auto *inputChannel = static_cast<float *>(inputBuffer->mBuffers[0].mData);
|
|
20
|
+
// writeToBuffers(inputChannel, numFrames);
|
|
21
|
+
// }
|
|
22
|
+
|
|
23
|
+
// while (circularBuffer_->getNumberOfAvailableFrames() >= bufferLength_) {
|
|
24
|
+
// auto bus = std::make_shared<AudioBus>(bufferLength_, 1, sampleRate_);
|
|
25
|
+
// auto *outputChannel = bus->getChannel(0)->getData();
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
auto bus = std::make_shared<AudioBus>(bufferLength_, 1, sampleRate_);
|
|
29
|
-
auto *outputChannel = bus->getChannel(0)->getData();
|
|
27
|
+
// circularBuffer_->pop_front(outputChannel, bufferLength_);
|
|
30
28
|
|
|
31
|
-
|
|
29
|
+
// invokeOnAudioReadyCallback(bus, bufferLength_);
|
|
30
|
+
// }
|
|
31
|
+
// };
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
IOSAudioRecorder::IOSAudioRecorder(const std::shared_ptr<AudioEventHandlerRegistry> &audioEventHandlerRegistry)
|
|
34
|
+
: AudioRecorder(audioEventHandlerRegistry), fileWriter_(nullptr)
|
|
35
|
+
{
|
|
36
|
+
AudioReceiverBlock receiverBlock = ^(const AudioBufferList *inputBuffer, int numFrames) {
|
|
37
|
+
if (usesFileOutput()) {
|
|
38
|
+
fileWriter_->writeAudioData(inputBuffer, numFrames);
|
|
34
39
|
}
|
|
35
40
|
};
|
|
36
41
|
|
|
37
|
-
|
|
38
|
-
bufferLength:bufferLength
|
|
39
|
-
sampleRate:sampleRate];
|
|
42
|
+
nativeRecorder_ = [[NativeAudioRecorder alloc] initWithReceiverBlock:receiverBlock];
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
IOSAudioRecorder::~IOSAudioRecorder()
|
|
43
46
|
{
|
|
44
47
|
stop();
|
|
45
|
-
[
|
|
48
|
+
[nativeRecorder_ cleanup];
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
void IOSAudioRecorder::start()
|
|
49
52
|
{
|
|
50
|
-
if (
|
|
53
|
+
if (isRecording()) {
|
|
51
54
|
return;
|
|
52
55
|
}
|
|
53
56
|
|
|
54
|
-
|
|
57
|
+
if (usesFileOutput()) {
|
|
58
|
+
fileWriter_->openFile([nativeRecorder_ getInputFormat]);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (usesCallback()) {
|
|
62
|
+
// TODO: create circular buffer and converter?
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (isConnected()) {
|
|
66
|
+
// TODO: set adapter node properties?
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
[nativeRecorder_ start];
|
|
55
70
|
isRunning_.store(true);
|
|
56
71
|
}
|
|
57
72
|
|
|
58
|
-
|
|
73
|
+
std::string IOSAudioRecorder::stop()
|
|
59
74
|
{
|
|
60
|
-
if (!
|
|
61
|
-
return;
|
|
75
|
+
if (!isRecording()) {
|
|
76
|
+
return std::string("");
|
|
62
77
|
}
|
|
63
78
|
|
|
79
|
+
[nativeRecorder_ stop];
|
|
64
80
|
isRunning_.store(false);
|
|
65
|
-
[audioRecorder_ stop];
|
|
66
81
|
|
|
67
|
-
|
|
82
|
+
// TODO: send remaining data?
|
|
83
|
+
|
|
84
|
+
if (usesFileOutput()) {
|
|
85
|
+
return fileWriter_->closeFile();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return std::string("");
|
|
68
89
|
}
|
|
69
90
|
|
|
91
|
+
void IOSAudioRecorder::enableFileOutput(
|
|
92
|
+
float sampleRate,
|
|
93
|
+
size_t channelCount,
|
|
94
|
+
size_t bitRate,
|
|
95
|
+
size_t iosFlags,
|
|
96
|
+
size_t androidFlags)
|
|
97
|
+
{
|
|
98
|
+
fileOutputEnabled_.store(true);
|
|
99
|
+
fileWriter_ = std::make_shared<IOSAudioFileWriter>(sampleRate, channelCount, bitRate, iosFlags);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
void IOSAudioRecorder::disableFileOutput()
|
|
103
|
+
{
|
|
104
|
+
fileOutputEnabled_.store(false);
|
|
105
|
+
fileWriter_ = nullptr;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
void IOSAudioRecorder::pause() {}
|
|
109
|
+
|
|
110
|
+
void IOSAudioRecorder::resume() {}
|
|
111
|
+
|
|
70
112
|
} // namespace audioapi
|
|
@@ -14,13 +14,9 @@ typedef void (^AudioReceiverBlock)(const AudioBufferList *inputBuffer, int numFr
|
|
|
14
14
|
@property (nonatomic, copy) AVAudioSinkNodeReceiverBlock receiverSinkBlock;
|
|
15
15
|
@property (nonatomic, copy) AudioReceiverBlock receiverBlock;
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
@property (nonatomic, strong) AVAudioFormat *inputFormat;
|
|
19
|
-
@property (nonatomic, strong) AVAudioFormat *outputFormat;
|
|
17
|
+
- (instancetype)initWithReceiverBlock:(AudioReceiverBlock)receiverBlock;
|
|
20
18
|
|
|
21
|
-
- (
|
|
22
|
-
bufferLength:(int)bufferLength
|
|
23
|
-
sampleRate:(float)sampleRate;
|
|
19
|
+
- (AVAudioFormat *)getInputFormat;
|
|
24
20
|
|
|
25
21
|
- (void)start;
|
|
26
22
|
|
|
@@ -5,40 +5,18 @@
|
|
|
5
5
|
@implementation NativeAudioRecorder
|
|
6
6
|
|
|
7
7
|
- (instancetype)initWithReceiverBlock:(AudioReceiverBlock)receiverBlock
|
|
8
|
-
bufferLength:(int)bufferLength
|
|
9
|
-
sampleRate:(float)sampleRate
|
|
10
8
|
{
|
|
11
9
|
if (self = [super init]) {
|
|
12
|
-
self.bufferLength = bufferLength;
|
|
13
|
-
self.sampleRate = sampleRate;
|
|
14
|
-
|
|
15
10
|
self.receiverBlock = [receiverBlock copy];
|
|
16
11
|
|
|
17
|
-
float devicePrefferedSampleRate = [[AVAudioSession sharedInstance] sampleRate];
|
|
18
|
-
|
|
19
|
-
if (!devicePrefferedSampleRate) {
|
|
20
|
-
NSError *error;
|
|
21
|
-
devicePrefferedSampleRate = sampleRate;
|
|
22
|
-
|
|
23
|
-
[[AVAudioSession sharedInstance] setPreferredSampleRate:sampleRate error:&error];
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
self.inputFormat = [[AVAudioFormat alloc] initWithCommonFormat:AVAudioPCMFormatFloat32
|
|
27
|
-
sampleRate:devicePrefferedSampleRate
|
|
28
|
-
channels:1
|
|
29
|
-
interleaved:NO];
|
|
30
|
-
self.outputFormat = [[AVAudioFormat alloc] initWithCommonFormat:AVAudioPCMFormatFloat32
|
|
31
|
-
sampleRate:sampleRate
|
|
32
|
-
channels:1
|
|
33
|
-
interleaved:NO];
|
|
34
|
-
self.audioConverter = [[AVAudioConverter alloc] initFromFormat:self.inputFormat toFormat:self.outputFormat];
|
|
35
|
-
|
|
36
12
|
__weak typeof(self) weakSelf = self;
|
|
37
13
|
self.receiverSinkBlock = ^OSStatus(
|
|
38
14
|
const AudioTimeStamp *_Nonnull timestamp,
|
|
39
15
|
AVAudioFrameCount frameCount,
|
|
40
16
|
const AudioBufferList *_Nonnull inputData) {
|
|
41
|
-
|
|
17
|
+
weakSelf.receiverBlock(inputData, frameCount);
|
|
18
|
+
|
|
19
|
+
return kAudioServicesNoError;
|
|
42
20
|
};
|
|
43
21
|
|
|
44
22
|
self.sinkNode = [[AVAudioSinkNode alloc] initWithReceiverBlock:self.receiverSinkBlock];
|
|
@@ -47,55 +25,9 @@
|
|
|
47
25
|
return self;
|
|
48
26
|
}
|
|
49
27
|
|
|
50
|
-
- (
|
|
51
|
-
withFrameCount:(AVAudioFrameCount)frameCount
|
|
52
|
-
atTimestamp:(const AudioTimeStamp *)timestamp
|
|
28
|
+
- (AVAudioFormat *)getInputFormat
|
|
53
29
|
{
|
|
54
|
-
|
|
55
|
-
float outputSampleRate = self.outputFormat.sampleRate;
|
|
56
|
-
|
|
57
|
-
if (inputSampleRate != outputSampleRate) {
|
|
58
|
-
AVAudioPCMBuffer *inputBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:self.inputFormat
|
|
59
|
-
frameCapacity:frameCount];
|
|
60
|
-
memcpy(
|
|
61
|
-
inputBuffer.mutableAudioBufferList->mBuffers[0].mData,
|
|
62
|
-
inputData->mBuffers[0].mData,
|
|
63
|
-
inputData->mBuffers[0].mDataByteSize);
|
|
64
|
-
inputBuffer.frameLength = frameCount;
|
|
65
|
-
|
|
66
|
-
int outputFrameCount = frameCount * outputSampleRate / inputSampleRate;
|
|
67
|
-
|
|
68
|
-
AVAudioPCMBuffer *outputBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:self.audioConverter.outputFormat
|
|
69
|
-
frameCapacity:outputFrameCount];
|
|
70
|
-
|
|
71
|
-
NSError *error = nil;
|
|
72
|
-
AVAudioConverterInputBlock inputBlock =
|
|
73
|
-
^AVAudioBuffer *_Nullable(AVAudioPacketCount inNumberOfPackets, AVAudioConverterInputStatus *outStatus)
|
|
74
|
-
{
|
|
75
|
-
*outStatus = AVAudioConverterInputStatus_HaveData;
|
|
76
|
-
return inputBuffer;
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
/// IMPORTANT: AVAudioConverter leaks memory without autorelease pool
|
|
80
|
-
/// more details here: https://github.com/poneciak57/AVAudioConverter-memory-leak-repro-electric-boogaloo
|
|
81
|
-
/// we can try to remove it in the future or refactor to reuse buffers to minimize allocations
|
|
82
|
-
@autoreleasepool {
|
|
83
|
-
[self.audioConverter convertToBuffer:outputBuffer error:&error withInputFromBlock:inputBlock];
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (error) {
|
|
87
|
-
NSLog(@"Error during audio conversion: %@", error.localizedDescription);
|
|
88
|
-
return kAudioServicesBadSpecifierSizeError;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
self.receiverBlock(outputBuffer.audioBufferList, outputBuffer.frameLength);
|
|
92
|
-
|
|
93
|
-
return kAudioServicesNoError;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
self.receiverBlock(inputData, frameCount);
|
|
97
|
-
|
|
98
|
-
return kAudioServicesNoError;
|
|
30
|
+
return [AudioEngine.sharedInstance.audioEngine.inputNode inputFormatForBus:0];
|
|
99
31
|
}
|
|
100
32
|
|
|
101
33
|
- (void)start
|
|
@@ -118,9 +118,9 @@ static AudioEngine *_sharedInstance = nil;
|
|
|
118
118
|
- (void)stopEngine
|
|
119
119
|
{
|
|
120
120
|
NSLog(@"[AudioEngine] stopEngine");
|
|
121
|
-
if (![self.audioEngine isRunning]) {
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
121
|
+
// if (![self.audioEngine isRunning]) {
|
|
122
|
+
// return;
|
|
123
|
+
// }
|
|
124
124
|
|
|
125
125
|
self.isSupposedToBeRunning = false;
|
|
126
126
|
[self.audioEngine stop];
|
|
@@ -213,15 +213,6 @@
|
|
|
213
213
|
|
|
214
214
|
- (void)requestRecordingPermissions:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject
|
|
215
215
|
{
|
|
216
|
-
id value = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSMicrophoneUsageDescription"];
|
|
217
|
-
// if there is no entry NSMicrophoneUsageDescription calling requestRecordPermission will quit an app
|
|
218
|
-
if (value == nil) {
|
|
219
|
-
reject(
|
|
220
|
-
nil,
|
|
221
|
-
@"There is no NSMicrophoneUsageDescription entry in info.plist file. App cannot access microphone without it.",
|
|
222
|
-
nil);
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
216
|
if (@available(iOS 17, *)) {
|
|
226
217
|
[AVAudioSession.sharedInstance requestRecordPermission:^(BOOL granted) {
|
|
227
218
|
if (granted) {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
@property (nonatomic, weak) MPNowPlayingInfoCenter *playingInfoCenter;
|
|
14
14
|
@property (nonatomic, copy) NSString *artworkUrl;
|
|
15
|
+
@property (nonatomic, assign) bool isReceivingRemoteCommands;
|
|
15
16
|
|
|
16
17
|
- (instancetype)initWithAudioAPIModule:(AudioAPIModule *)audioAPIModule;
|
|
17
18
|
- (void)cleanup;
|
|
@@ -19,28 +19,40 @@
|
|
|
19
19
|
if (self = [super init]) {
|
|
20
20
|
self.audioAPIModule = audioAPIModule;
|
|
21
21
|
self.playingInfoCenter = [MPNowPlayingInfoCenter defaultCenter];
|
|
22
|
+
self.isReceivingRemoteCommands = false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return self;
|
|
26
|
+
}
|
|
22
27
|
|
|
28
|
+
- (void)toggleRemoteCommands:(bool)enable
|
|
29
|
+
{
|
|
30
|
+
if (enable && !self.isReceivingRemoteCommands) {
|
|
31
|
+
self.isReceivingRemoteCommands = true;
|
|
23
32
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
24
33
|
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
|
|
25
34
|
});
|
|
35
|
+
return;
|
|
36
|
+
} else if (!enable && self.isReceivingRemoteCommands) {
|
|
37
|
+
self.isReceivingRemoteCommands = false;
|
|
38
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
39
|
+
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
|
|
40
|
+
});
|
|
41
|
+
return;
|
|
26
42
|
}
|
|
27
|
-
|
|
28
|
-
return self;
|
|
29
43
|
}
|
|
30
44
|
|
|
31
45
|
- (void)cleanup
|
|
32
46
|
{
|
|
33
47
|
NSLog(@"[LockScreenManager] cleanup");
|
|
48
|
+
[self toggleRemoteCommands:false];
|
|
34
49
|
[self resetLockScreenInfo];
|
|
35
|
-
|
|
36
|
-
dispatch_async(dispatch_get_main_queue(), ^{
|
|
37
|
-
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
|
|
38
|
-
});
|
|
39
50
|
}
|
|
40
51
|
|
|
41
52
|
- (void)setLockScreenInfo:(NSDictionary *)info
|
|
42
53
|
{
|
|
43
54
|
self.playingInfoCenter = [MPNowPlayingInfoCenter defaultCenter];
|
|
55
|
+
[self toggleRemoteCommands:true];
|
|
44
56
|
|
|
45
57
|
// now playing info(lock screen info)
|
|
46
58
|
NSMutableDictionary *lockScreenInfoDict;
|
|
@@ -79,6 +91,7 @@
|
|
|
79
91
|
|
|
80
92
|
- (void)resetLockScreenInfo
|
|
81
93
|
{
|
|
94
|
+
[self toggleRemoteCommands:false];
|
|
82
95
|
self.playingInfoCenter = [MPNowPlayingInfoCenter defaultCenter];
|
|
83
96
|
self.playingInfoCenter.nowPlayingInfo = nil;
|
|
84
97
|
self.artworkUrl = nil;
|