Reputation: 1944
I have a AVPlayer
with AVPlayerItem
. What I want is to turn off the audio playback in the AVPlayer
. I want to play only video, no audio.
Here's what I have so far:
self.avPlayerItem = [AVPlayerItem playerItemWithURL:self.videoUrl];
self.avPlayer = [AVPlayer playerWithPlayerItem:self.avPlayerItem];
[self.avPlayer play];
self.avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
self.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer];
self.avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidPlayToEndTime:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:self.avPlayerItem];
CGRect screenRect = [[UIScreen mainScreen] bounds];
self.avPlayerLayer.frame = CGRectMake(0, 0, screenRect.size.width, screenRect.size.height);
[self.view.layer insertSublayer:self.avPlayerLayer atIndex:0];
Upvotes: 27
Views: 24498
Reputation: 21681
You can mute the audio by implementing following code into viewDidLoad()
.
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:[self myAssetURL]
options:nil];
NSArray *audioTracks = [asset tracksWithMediaType:AVMediaTypeAudio];
// Mute all the audio
tracksNSMutableArray *allAudioParams = [NSMutableArray array];
for (AVAssetTrack *track in audioTracks) {
AVMutableAudioMixInputParameters *audioInputParams
=[AVMutableAudioMixInputParameters audioMixInputParameters];
[audioInputParams setVolume:0.0 atTime:kCMTimeZero];
[audioInputParams setTrackID:[track trackID]]; [allAudioParams
addObject:audioInputParams];}
AVMutableAudioMix *audioZeroMix =
[AVMutableAudioMix audioMix];
[audioZeroMix setInputParameters:allAudioParams];
Following links may help you.
Upvotes: -1
Reputation: 7912
As @Tung Fam's answer suggests, you can easily do this in your app to mute a video:
player.isMuted = true
You may run a video on mute using the code above, the problem is, if you simply use isMuted = true
(for let's say the video preview) it will work, but your app will "hijack" any existing system AVAudioSession
. This means if the user was, let's say, listening to music (Spotify or Apple Music), their music would get interrupted. This is because app's have AVAudioSession
set to AVAudioSessionCategorySoloAmbient
by default, therefore your app will ALWAYS interrupt all running audio sessions in the background as soon as it starts playing a video, muted or un-muted. This may not be a very pleasing user experience and lead to confusion.
What you may want to do is show your video muted as a preview while the user continues to play their song in the background. When user goes to full screen with your app's video, any background audio must "pause" or be "interrupted"; essentially your app will take over the AVAudioSession
. Then, once you are done playing your video let the "interrupted" background audio (e.g. Spotify, Apple Music, etc.) resume. The steps below achieve a behavior similar to how Twitter handles videos and background music:
In your AppDelegate's didFinishLaunchingWithOptions
method make sure your app is not interrupting any background music. Because your videos would be running in "mute" you can simply mixWithOthers
.
do {
try AVAudioSession.sharedInstance().setCategory(
AVAudioSession.Category.playback,
options: [.mixWithOthers]
)
try AVAudioSession.sharedInstance().setActive(true)
} catch { /* some meaningful exception handling */ }
When your App starts to play your video Full screen (un-muted/with sound), you must now interrupt any background music. For that, before your player.play()
you can set the AVAudioSession
again, like so-
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback)
try AVAudioSession.sharedInstance().setActive(true)
} catch { /* some meaningful exception handling */ }
This will basically pause/interrupt any background audio in progress and let your video play with sound.
Once your video is done playing with sound, you must now let the AVAudioSession
know that it can resume any audio session that was interrupted by you (i.e. Spotify, Apple Music, map navigation instructions etc.). To do that, once your video stops playing you can do this:
do {
try AVAudioSession.sharedInstance().setCategory(
AVAudioSession.Category.playback,
options: [.mixWithOthers]
)
try AVAudioSession.sharedInstance().setActive(false, options: AVAudioSession.SetActiveOptions.notifyOthersOnDeactivation)
} catch { /* Some meaningful exception handling */ }
There are a lot more options available on how to handle AVAudioSession
. Here's the documentation, and here are Apple's guidelines on using AVAudioSession
for different types of apps.
This is just a very basic explanation on how AVAudioSession
can be used, but depending on your app's functionality there may be a need to use KVOs, AppDelegate methods (for app going to background and or coming to foreground and so on) to set the AVAudioSession
appropriately. Further caveat is that you really need to play around with all the options on AVAudioSession
since it may not work the way you think it should so it could become a little grueling. Even more caveat is that surprisingly I've found very little online that goes into detail with AVAudioSession
except for Apple's documentation and a few questions here on SO.
Bottom line is: if your app deals with audio/video then it is HIGHLY recommended to handle AVAudioSession
appropriately based on Apple's playbook of "Audio Guidelines By App Type"... maybe not when you launch your app but definitely as your app matures and becomes more stable.
Upvotes: 50
Reputation: 527
You can add this in the AppDelegate didFinishLaunchingWithOptions. If you don't want your video to stop the sound that is currently played on other apps (even if your video player is set to mute)
func setAudioMix(){
do{
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, options: [.mixWithOthers])
try AVAudioSession.sharedInstance().setActive(true)
}catch{
print("something went wrong")
}
}
Upvotes: 2
Reputation: 8147
In case someone is looking for Swift 4:
player.isMuted = true // To mute the sound
player.isMuted = false // To un-mute the sound
Side note: muting the video does not reset the video sound to start. It works as just a common sense mute feature.
Upvotes: 7
Reputation: 1450
AVPlayer have option
@property (nonatomic, getter=isMuted) BOOL muted NS_AVAILABLE(10_7, 7_0);
You can write
- (void) muteSound:(BOOL)mute
{
self.avPlayer.muted = mute;
}
And use it, how you want
- (void) startPlayingVideo
{
[self muteSound:YES];
//other code
}
Upvotes: 25