react-native-audio-waveform icon indicating copy to clipboard operation
react-native-audio-waveform copied to clipboard

iOS Playback Has No Sound in Silent Mode

Open imrankhanpersonalai opened this issue 9 months ago • 3 comments

Description: On iOS devices, audio playback using @simform_solutions/react-native-audio-waveform is completely silent when the device is in silent mode. This is due to the current AVAudioSession category being set to .playAndRecord or a default that doesn’t override silent mode behavior.

Expected Behavior: Audio should play regardless of the device's silent mode switch — consistent with user expectations for media playback apps.

Root Cause: The AVAudioSession category used during playback is likely not .playback, which is required for audio to play in silent mode on iOS.

Proposed Fix: https://developer.apple.com/documentation/avfaudio/avaudiosession/category-swift.struct/playback try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, options: options)

imrankhanpersonalai avatar May 04 '25 21:05 imrankhanpersonalai

Having this problem

keuvy avatar May 29 '25 17:05 keuvy

we are also having this problem

NonkelDaniel avatar Jul 14 '25 16:07 NonkelDaniel

I fixed it via expo config plugin.

/* eslint-disable @typescript-eslint/no-require-imports */
const { withDangerousMod } = require('@expo/config-plugins');
const fs = require('fs');
const path = require('path');

const project = 'personalaiatt';
const audioCategory = `
	// Set audio session category to playback
	do {
		try AVAudioSession.sharedInstance().setCategory(.playback)
		try AVAudioSession.sharedInstance().setActive(true)
	} catch {
		print("Failed to set audio session category: \\(error)")
	}
`;

const AVAudioPlayback = (config) =>
	withDangerousMod(config, [
		'ios',
		(mod) => {
			const appDelegatePath = path.join(mod.modRequest.projectRoot, 'ios', project, 'AppDelegate.swift');
			if (!fs.existsSync(appDelegatePath)) {
				throw new Error('AppDelegate.swift not found at expected path: ' + appDelegatePath);
			}

			let contents = fs.readFileSync(appDelegatePath, 'utf-8');
			if (contents.includes('AVAudioSession.sharedInstance().setCategory')) return mod;
			if (!contents.includes('import AVFoundation')) {
				contents = contents.replace(/import (Expo|UIKit)/, (match) => `import AVFoundation\n${match}`);
			}
			contents = contents.replace(
				/return super\.application\(application, didFinishLaunchingWithOptions: launchOptions\)/,
				`${audioCategory}\n    return super.application(application, didFinishLaunchingWithOptions: launchOptions)`
			);

			fs.writeFileSync(appDelegatePath, contents);

			return mod;
		}
	]);

module.exports.AVAudioPlayback = AVAudioPlayback;

imrankhanpersonalai avatar Jul 14 '25 16:07 imrankhanpersonalai