Skip to content

Commit

Permalink
Assign file extension based on audio format
Browse files Browse the repository at this point in the history
  • Loading branch information
jbaudanza committed Jun 16, 2024
1 parent f97f923 commit 2454b04
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,13 @@ class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationCont
promise.reject("No permission granted.", "Try again after adding permission.")
return
}
audioFileURL = if (((path == "DEFAULT"))) "${reactContext.cacheDir}/$defaultFileName" else path

var outputFormat = if (audioSet != null && audioSet.hasKey("OutputFormatAndroid"))
audioSet.getInt("OutputFormatAndroid")
else
MediaRecorder.OutputFormat.MPEG_4

audioFileURL = if (((path == "DEFAULT"))) "${reactContext.cacheDir}/sound.${defaultFileExtensions.get(outputFormat)}" else path
_meteringEnabled = meteringEnabled

if (mediaRecorder == null) {
Expand All @@ -69,14 +75,14 @@ class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationCont

if (audioSet != null) {
mediaRecorder!!.setAudioSource(if (audioSet.hasKey("AudioSourceAndroid")) audioSet.getInt("AudioSourceAndroid") else MediaRecorder.AudioSource.MIC)
mediaRecorder!!.setOutputFormat(if (audioSet.hasKey("OutputFormatAndroid")) audioSet.getInt("OutputFormatAndroid") else MediaRecorder.OutputFormat.MPEG_4)
mediaRecorder!!.setOutputFormat(outputFormat)
mediaRecorder!!.setAudioEncoder(if (audioSet.hasKey("AudioEncoderAndroid")) audioSet.getInt("AudioEncoderAndroid") else MediaRecorder.AudioEncoder.AAC)
mediaRecorder!!.setAudioSamplingRate(if (audioSet.hasKey("AudioSamplingRateAndroid")) audioSet.getInt("AudioSamplingRateAndroid") else 48000)
mediaRecorder!!.setAudioEncodingBitRate(if (audioSet.hasKey("AudioEncodingBitRateAndroid")) audioSet.getInt("AudioEncodingBitRateAndroid") else 128000)
mediaRecorder!!.setAudioChannels(if (audioSet.hasKey("AudioChannelsAndroid")) audioSet.getInt("AudioChannelsAndroid") else 2)
} else {
mediaRecorder!!.setAudioSource(MediaRecorder.AudioSource.MIC)
mediaRecorder!!.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
mediaRecorder!!.setOutputFormat(outputFormat)
mediaRecorder!!.setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
mediaRecorder!!.setAudioEncodingBitRate(128000)
mediaRecorder!!.setAudioSamplingRate(48000)
Expand Down Expand Up @@ -381,5 +387,19 @@ class RNAudioRecorderPlayerModule(private val reactContext: ReactApplicationCont
companion object {
private var tag = "RNAudioRecorderPlayer"
private var defaultFileName = "sound.mp4"
private var defaultFileExtensions = listOf(
"mp4", // DEFAULT = 0,
"3gp", // THREE_GPP,
"mp4", // MPEG_4,
"amr", // AMR_NB,
"amr", // AMR_WB,
"aac", // AAC_ADIF,
"aac", // AAC_ADTS,
"rtp", // OUTPUT_FORMAT_RTP_AVP,
"ts", // MPEG_2_TSMPEG_2_TS,
"webm",// WEBM
"xxx", // UNUSED
"ogg", // OGG
)
}
}
3 changes: 3 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export enum OutputFormatAndroidType {
OUTPUT_FORMAT_RTP_AVP,
MPEG_2_TS,
WEBM,
UNUSED,
OGG,
}

export enum AudioEncoderAndroidType {
Expand All @@ -44,6 +46,7 @@ export enum AudioEncoderAndroidType {
HE_AAC,
AAC_ELD,
VORBIS,
OPUS,
}

export enum AVEncodingOption {
Expand Down
138 changes: 98 additions & 40 deletions ios/RNAudioRecorderPlayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -184,55 +184,26 @@ class RNAudioRecorderPlayer: RCTEventEmitter, AVAudioRecorderDelegate {
let avLPCMIsFloatKey = audioSets["AVLinearPCMIsFloatKeyIOS"] as? Bool
let avLPCMIsNonInterleaved = audioSets["AVLinearPCMIsNonInterleavedIOS"] as? Bool

var avFormat: Int? = nil
var avMode: AVAudioSession.Mode = AVAudioSession.Mode.default
var sampleRate = audioSets["AVSampleRateKeyIOS"] as? Int
var numberOfChannel = audioSets["AVNumberOfChannelsKeyIOS"] as? Int
var audioQuality = audioSets["AVEncoderAudioQualityKeyIOS"] as? Int
var bitRate = audioSets["AVEncoderBitRateKeyIOS"] as? Int

setAudioFileURL(path: path)

if (sampleRate == nil) {
sampleRate = 44100;
}

if (encoding == nil) {
avFormat = Int(kAudioFormatAppleLossless)
guard let avFormat: AudioFormatID = avFormat(fromString: encoding) else {
return reject("RNAudioPlayerRecorder", "Audio format not available", nil)
}

if (path == "DEFAULT") {
let cachesDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
let fileExt = fileExtension(forAudioFormat: avFormat)
audioFileURL = cachesDirectory.appendingPathComponent("sound." + fileExt)
} else {
if (encoding == "lpcm") {
avFormat = Int(kAudioFormatAppleIMA4)
} else if (encoding == "ima4") {
avFormat = Int(kAudioFormatAppleIMA4)
} else if (encoding == "aac") {
avFormat = Int(kAudioFormatMPEG4AAC)
} else if (encoding == "MAC3") {
avFormat = Int(kAudioFormatMACE3)
} else if (encoding == "MAC6") {
avFormat = Int(kAudioFormatMACE6)
} else if (encoding == "ulaw") {
avFormat = Int(kAudioFormatULaw)
} else if (encoding == "alaw") {
avFormat = Int(kAudioFormatALaw)
} else if (encoding == "mp1") {
avFormat = Int(kAudioFormatMPEGLayer1)
} else if (encoding == "mp2") {
avFormat = Int(kAudioFormatMPEGLayer2)
} else if (encoding == "mp4") {
avFormat = Int(kAudioFormatMPEG4AAC)
} else if (encoding == "alac") {
avFormat = Int(kAudioFormatAppleLossless)
} else if (encoding == "amr") {
avFormat = Int(kAudioFormatAMR)
} else if (encoding == "flac") {
if #available(iOS 11.0, *) {
avFormat = Int(kAudioFormatFLAC)
}
} else if (encoding == "opus") {
avFormat = Int(kAudioFormatOpus)
} else if (encoding == "wav") {
avFormat = Int(kAudioFormatLinearPCM)
}
setAudioFileURL(path: path)
}

if (mode == "measurement") {
Expand Down Expand Up @@ -273,14 +244,14 @@ class RNAudioRecorderPlayer: RCTEventEmitter, AVAudioRecorderDelegate {
func startRecording() {
let settings = [
AVSampleRateKey: sampleRate!,
AVFormatIDKey: avFormat!,
AVFormatIDKey: avFormat,
AVNumberOfChannelsKey: numberOfChannel!,
AVEncoderAudioQualityKey: audioQuality!,
AVLinearPCMBitDepthKey: avLPCMBitDepth ?? AVLinearPCMBitDepthKey.count,
AVLinearPCMIsBigEndianKey: avLPCMIsBigEndian ?? true,
AVLinearPCMIsFloatKey: avLPCMIsFloatKey ?? false,
AVLinearPCMIsNonInterleaved: avLPCMIsNonInterleaved ?? false,
AVEncoderBitRateKey: bitRate!
AVEncoderBitRateKey: bitRate!
] as [String : Any]

do {
Expand Down Expand Up @@ -493,4 +464,91 @@ class RNAudioRecorderPlayer: RCTEventEmitter, AVAudioRecorderDelegate {
audioPlayer.volume = volume
resolve(volume)
}
private func avFormat(fromString encoding: String?) -> AudioFormatID? {
if (encoding == nil) {
return kAudioFormatAppleLossless
} else {
if (encoding == "lpcm") {
return kAudioFormatAppleIMA4
} else if (encoding == "ima4") {
return kAudioFormatAppleIMA4
} else if (encoding == "aac") {
return kAudioFormatMPEG4AAC
} else if (encoding == "MAC3") {
return kAudioFormatMACE3
} else if (encoding == "MAC6") {
return kAudioFormatMACE6
} else if (encoding == "ulaw") {
return kAudioFormatULaw
} else if (encoding == "alaw") {
return kAudioFormatALaw
} else if (encoding == "mp1") {
return kAudioFormatMPEGLayer1
} else if (encoding == "mp2") {
return kAudioFormatMPEGLayer2
} else if (encoding == "mp4") {
return kAudioFormatMPEG4AAC
} else if (encoding == "alac") {
return kAudioFormatAppleLossless
} else if (encoding == "amr") {
return kAudioFormatAMR
} else if (encoding == "flac") {
if #available(iOS 11.0, *) {
return kAudioFormatFLAC
}
} else if (encoding == "opus") {
return kAudioFormatOpus
} else if (encoding == "wav") {
return kAudioFormatLinearPCM
}
}
return nil;
}

private func fileExtension(forAudioFormat format: AudioFormatID) -> String {
switch format {
case kAudioFormatOpus:
return "ogg"
case kAudioFormatLinearPCM:
return "wav"
case kAudioFormatAC3, kAudioFormat60958AC3:
return "ac3"
case kAudioFormatAppleIMA4:
return "caf"
case kAudioFormatMPEG4AAC, kAudioFormatMPEG4CELP, kAudioFormatMPEG4HVXC, kAudioFormatMPEG4TwinVQ, kAudioFormatMPEG4AAC_HE, kAudioFormatMPEG4AAC_LD, kAudioFormatMPEG4AAC_ELD, kAudioFormatMPEG4AAC_ELD_SBR, kAudioFormatMPEG4AAC_ELD_V2, kAudioFormatMPEG4AAC_HE_V2, kAudioFormatMPEG4AAC_Spatial:
return "m4a"
case kAudioFormatMACE3, kAudioFormatMACE6:
return "caf"
case kAudioFormatULaw, kAudioFormatALaw:
return "wav"
case kAudioFormatQDesign, kAudioFormatQDesign2:
return "mov"
case kAudioFormatQUALCOMM:
return "qcp"
case kAudioFormatMPEGLayer1:
return "mp1"
case kAudioFormatMPEGLayer2:
return "mp2"
case kAudioFormatMPEGLayer3:
return "mp3"
case kAudioFormatMIDIStream:
return "mid"
case kAudioFormatAppleLossless:
return "m4a"
case kAudioFormatAMR:
return "amr"
case kAudioFormatAMR_WB:
return "awb"
case kAudioFormatAudible:
return "aa"
case kAudioFormatiLBC:
return "ilbc"
case kAudioFormatDVIIntelIMA, kAudioFormatMicrosoftGSM:
return "wav"
default:
// Generic file extension for types that don't have a natural
// file extension
return "audio"
}
}
}

0 comments on commit 2454b04

Please sign in to comment.