public void SetupAudio(int sampleRate, int channels, byte[] esdsData) { _audioTrack = new AudioTrack( new AudioAttributes.Builder() .SetUsage(AudioUsageKind.Media) .SetContentType(AudioContentType.Music) .SetFlags(AudioFlags.LowLatency) .Build(), new Android.Media.AudioFormat.Builder() .SetEncoding(Encoding.Pcm16bit) .SetSampleRate(44100) .SetChannelMask(ChannelOut.Stereo) .Build(), 4096, AudioTrackMode.Stream, AudioManager.AudioSessionIdGenerate); MediaFormat audioFormat = MediaFormat.CreateAudioFormat( mime: MediaFormat.MimetypeAudioAac, sampleRate: sampleRate, channelCount: channels); audioFormat.SetInteger(MediaFormat.KeyIsAdts, 0); audioFormat.SetInteger(MediaFormat.KeyAacProfile, (int)MediaCodecProfileType.Aacobjectlc); _audioCodec = MediaCodec.CreateDecoderByType( MediaFormat.MimetypeAudioAac); // TODO: Remove hardcoding byte profile = (byte)MediaCodecProfileType.Aacobjectlc; byte sampleIndex = AacAdtsAssembler.GetSamplingFrequencyIndex(sampleRate); byte[] csd0 = new byte[2]; csd0[0] = (byte)(((byte)profile << 3) | (sampleIndex >> 1)); csd0[1] = (byte)((byte)((sampleIndex << 7) & 0x80) | (channels << 3)); esdsData = csd0; audioFormat.SetByteBuffer("csd-0", Java.Nio.ByteBuffer.Wrap(esdsData)); _audioCodec.SetCallback(this); _audioCodec.Configure( format: audioFormat, surface: null, crypto: null, flags: MediaCodecConfigFlags.None); _audioCodec.Start(); _audioTrack.Play(); }
public MediaFormat CreateAudioOutputFormat(MediaFormat inputFormat) { if (mAudioBitrate == AUDIO_BITRATE_AS_IS || mAudioChannels == AUDIO_CHANNELS_AS_IS) { return(null); } // Use original sample rate, as resampling is not supported yet. MediaFormat format = MediaFormat.CreateAudioFormat(MediaFormatExtraConstants.MimetypeAudioAac, inputFormat.GetInteger(MediaFormat.KeySampleRate), mAudioChannels); // this is obsolete: MediaCodecInfo.CodecProfileLevel.AACObjectLC, so using MediaCodecProfileType.Aacobjectlc instead format.SetInteger(MediaFormat.KeyAacProfile, (int)MediaCodecProfileType.Aacobjectlc); format.SetInteger(MediaFormat.KeyBitRate, mAudioBitrate); return(format); }
public static MediaFormat GetMediaFormat(string mimeType, int sampleRate, int channels) { var format = MediaFormat.CreateAudioFormat( mime: MediaFormat.MimetypeAudioAac, sampleRate: sampleRate, channelCount: channels); format.SetInteger(MediaFormat.KeyIsAdts, 0); format.SetInteger(MediaFormat.KeyAacProfile, (int)MediaCodecProfileType.Aacobjectlc); byte profile = (byte)MediaCodecProfileType.Aacobjectlc; byte sampleIndex = AacAdtsAssembler.GetSamplingFrequencyIndex(sampleRate); byte[] csd0 = new byte[2]; csd0[0] = (byte)(((byte)profile << 3) | (sampleIndex >> 1)); csd0[1] = (byte)((byte)((sampleIndex << 7) & 0x80) | (channels << 3)); format.SetByteBuffer("csd-0", Java.Nio.ByteBuffer.Wrap(csd0)); return(format); }
// https://github.com/lanhq147/SampleMediaFrame/blob/e2f20ff9eef73318e5a9b4de15458c5c2eb0fd46/app/src/main/java/com/google/android/exoplayer2/video/av/HWRecorder.java public bool BeginEncoding(int resX, int resY, int rateNumer, int rateDenom, int videoBitRate, int audioBitRate, string audioFile, string outputFile) { videoBufferInfo = new MediaCodec.BufferInfo(); audioBufferInfo = new MediaCodec.BufferInfo(); frameRateNumer = rateNumer; frameRateDenom = rateDenom; MediaFormat videoFormat = MediaFormat.CreateVideoFormat(VideoMimeType, resX, resY); videoFormat.SetInteger(MediaFormat.KeyColorFormat, (int)MediaCodecCapabilities.Formatsurface); videoFormat.SetInteger(MediaFormat.KeyBitRate, videoBitRate * 1000); videoFormat.SetFloat(MediaFormat.KeyFrameRate, rateNumer / (float)rateDenom); videoFormat.SetInteger(MediaFormat.KeyIFrameInterval, 4); videoFormat.SetInteger(MediaFormat.KeyProfile, (int)MediaCodecProfileType.Avcprofilehigh); videoFormat.SetInteger(MediaFormat.KeyLevel, (int)MediaCodecProfileLevel.Avclevel31); videoEncoder = MediaCodec.CreateEncoderByType(VideoMimeType); videoEncoder.Configure(videoFormat, null, null, MediaCodecConfigFlags.Encode); surface = videoEncoder.CreateInputSurface(); videoEncoder.Start(); MediaFormat audioFormat = MediaFormat.CreateAudioFormat(AudioMimeType, 44100, 1); audioFormat.SetInteger(MediaFormat.KeyAacProfile, (int)MediaCodecProfileType.Aacobjectlc); audioFormat.SetInteger(MediaFormat.KeyBitRate, audioBitRate * 1000); audioEncoder = MediaCodec.CreateEncoderByType(AudioMimeType); audioEncoder.Configure(audioFormat, null, null, MediaCodecConfigFlags.Encode); audioEncoder.Start(); try { muxer = new MediaMuxer(outputFile, MuxerOutputType.Mpeg4); } catch { return(false); } videoTrackIndex = -1; audioTrackIndex = -1; muxerStarted = false; if (!ElgInitialize()) { return(false); } audioData = File.ReadAllBytes(audioFile); if (audioData == null) { return(false); } DrainEncoder(videoEncoder, videoBufferInfo, videoTrackIndex, false); DrainEncoder(audioEncoder, audioBufferInfo, audioTrackIndex, false); audioEncodingTask = Task.Factory.StartNew(AudioEncodeThread, TaskCreationOptions.LongRunning); return(true); }
public void TranscodeAudio(SourceMedia sourceMedia, TargetMedia targetMedia, TrimConfig trimConfig, TransformationState transformationState) { if (targetMedia.targetFile.Exists()) { targetMedia.targetFile.Delete(); } transformationState.requestId = UUID.RandomUUID().ToString(); /* MediaTransformationListener transformationListener = new MediaTransformationListener(context, transformationState.requestId, transformationState, targetMedia); */ MediaRange mediaRange = trimConfig.enabled ? new MediaRange( TimeUnit.Milliseconds.ToMicros((long)(trimConfig.range[0] * 1000)), TimeUnit.Milliseconds.ToMicros((long)(trimConfig.range[1] * 1000))) : new MediaRange(0, long.MaxValue); try { var targetMimeType = targetMedia.writeToWav ? "audio/raw" : "audio/mp4a-latm"; IMediaTarget mediaTarget; if (targetMedia.writeToWav) { mediaTarget = new WavMediaTarget(targetMedia.targetFile.Path); } else { mediaTarget = new MediaMuxerMediaTarget(targetMedia.targetFile.Path, 1, 0, (int)MuxerOutputType.Mpeg4); } var mediaSource = new MediaExtractorMediaSource(context, sourceMedia.uri, mediaRange); List<TrackTransform> trackTransforms = new List<TrackTransform>(1); foreach (TargetTrack targetTrack in targetMedia.tracks) { if (targetTrack.format is AudioTrackFormat trackFormat) { MediaFormat mediaFormat = MediaFormat.CreateAudioFormat( targetMimeType, trackFormat.samplingRate, trackFormat.channelCount); mediaFormat.SetInteger(MediaFormat.KeyBitRate, trackFormat.bitrate); mediaFormat.SetLong(MediaFormat.KeyDuration, trackFormat.duration); IEncoder encoder; if (targetMedia.writeToWav) { encoder = new PassthroughBufferEncoder(8192); } else { encoder = new MediaCodecEncoder(); } //IEncoder encoder = targetMedia.writeToWav ? new PassthroughBufferEncoder(8192) : new MediaCodecEncoder(); TrackTransform trackTransform = new TrackTransform.Builder(mediaSource, targetTrack.sourceTrackIndex, mediaTarget) .SetTargetTrack(0) .SetDecoder(new MediaCodecDecoder()) .SetEncoder(encoder) .SetRenderer(new AudioRenderer(encoder)) .SetTargetFormat(mediaFormat) .Build(); trackTransforms.Add(trackTransform); break; } } _mediaTransformer.Transform( transformationState.requestId, trackTransforms, this, MediaTransformer.GranularityDefault); } catch (System.Exception err) { System.Diagnostics.Debug.WriteLine($"Exception when trying to transcode audio: {err.Message}"); } }