Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setVolume not working on AVMutableAudioMixInputParameters with playing from phones local iPod library

I'm currently trying to play music from a phones local iPod library using AVPlayer rather than MPMusicPlayerController using the application controller.

I can get it select a track from the local iPod lib using and MPMediaQuery, but when I try to start the audio at a lower level using AVMutableAudioMixInputParameters, it doesn't seem to lower the volume at all.

The reason I'm using AVPlayer and not MPMusicPlayerController is that I'm playing some other audio in the background at the same time and MPMusicPlayerController fails to play as an existing audio file using AVPlayer is hogging the hardware. The code I have at the moment is:

// just blindly select all music for now.
MPMediaQuery *everything = [[MPMediaQuery alloc] init];

NSArray *itemsFromGenericQuery = [everything items];
MPMediaItem *song;
NSMutableArray *array = [[NSMutableArray alloc] init];

for (song in itemsFromGenericQuery) 
{
    [array addObject:song];
}

So at this point array is an array of tracks from my lib.

Now to grab one and play it using AVPlayer:

// grab the first song off the array
MPMediaItem *song = [array objectAtIndex:0];
NSURL *assetURL = [song valueForProperty:MPMediaItemPropertyAssetURL];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:assetURL options:nil];

NSArray *audioTracks = [asset tracksWithMediaType:AVMediaTypeAudio];
AVAssetTrack *track = [audioTracks objectAtIndex:0];

NSMutableArray *allAudioParams = [NSMutableArray array];
AVMutableAudioMixInputParameters *audioInputParams = 
        [AVMutableAudioMixInputParameters audioMixInputParameters];

// this is the key line - turn the volume down.
[audioInputParams setVolume:0.3 atTime:kCMTimeZero];
[audioInputParams setTrackID:[track trackID]];
[allAudioParams addObject:audioInputParams];

AVMutableAudioMix *audioZeroMix = [AVMutableAudioMix audioMix];
[audioZeroMix setInputParameters:allAudioParams];

// Create a player item
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];

[playerItem setAudioMix:audioZeroMix];
[playerItem seekToTime:CMTimeMake(30, 1)];

[self setLocalPlayer:[AVPlayer playerWithPlayerItem:playerItem]];
[localPlayer play];

I can confirm that adjusting the volume works when using AVPlayer to play files from a URL (streaming); just not when playing from the local library.

I realise I haven't done any memory management here; just trying to get it working first. Also, local player is a property so there is no explicit retain.

Any help would be greatly appreciated!

Thanks.

like image 406
Ben Novakovic Avatar asked Nov 06 '22 03:11

Ben Novakovic


2 Answers

AVMutableAudioMix is only available for File Based Media, not Live http streaming.

like image 64
Iain McLean Avatar answered Nov 15 '22 04:11

Iain McLean


This work for me (fade in):

NSString *songName = [NSString stringWithFormat:@"http://xx.xx.xx.xx/%d%@", bitrate, url];
playerItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:songName]];

NSArray *audioTracks = [[playerItem asset] tracks];

AVMutableAudioMixInputParameters *audioInputParams = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:audioTracks[0]];
[audioInputParams setVolumeRampFromStartVolume:0.0 toEndVolume:1.0 timeRange:CMTimeRangeMake(CMTimeMakeWithSeconds(0.0, 1.0), CMTimeMakeWithSeconds(3.0, 1.0))];

AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
[audioMix setInputParameters:@[audioInputParams]];

[playerItem setAudioMix:audioMix];

AVPlayer *player = [[AVPlayer alloc] initWithPlayerItem:playerItem];

when user skip to next track or track almost finished I call function:

- (void)fadeOut {
    seconds = CMTimeGetSeconds(playerItem.currentTime);

    NSArray *audioTracks = [[playerItem asset] tracks];

    AVMutableAudioMixInputParameters *audioInputParams = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:audioTracks[0]];
    [audioInputParams setVolumeRampFromStartVolume:1.0 toEndVolume:0.0 timeRange:CMTimeRangeMake(CMTimeMakeWithSeconds(seconds, 1.0), CMTimeMakeWithSeconds(3.0, 1.0))];

    AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
    [audioMix setInputParameters:@[audioInputParams]];

    [playerItem setAudioMix:audioMix];
}
like image 23
Maxim Avatar answered Nov 15 '22 05:11

Maxim