Как отключить звук/включить звук при воспроизведении видео с помощью MPMoviePlayerController?
Я создал свои собственные элементы управления для использования с MPMoviePlayerController
. Пока все работает, кроме элемента управления кнопки отключения звука.
Я сконфигурировал AVAudioSession
, используя следующий код, прежде чем создать свой экземпляр MPMoviePlayerController
.
NSError *modeError = nil;
[self.audioSession setMode:AVAudioSessionModeMoviePlayback error:&modeError];
if (modeError != nil) {
NSLog(@"Error setting mode for AVAudioSession: %@", modeError);
}
NSError *categoryError = nil;
[self.audioSession setCategory:AVAudioSessionCategoryPlayback error:&categoryError];
if (categoryError != nil) {
NSLog(@"Error setting category for AVAudioSession: %@", categoryError);
}
Затем в моем методе обратного вызова кнопки mute у меня есть следующий код:
NSError *activeError = nil;
[self.audioSession setActive:NO error:&activeError];
if (activeError != nil) {
NSLog(@"Error setting inactive state for AVAudioSession: %@", activeError);
}
При нажатии кнопки Mute я получаю следующую неиспользуемую ошибку:
Error Domain=NSOSStatusErrorDomain Code=560030580 "The operation couldn’t be completed. (OSStatus error 560030580.)"
Я привязываюсь к структуре AVFoundation
.
Это действительно начинает меня бигать, поскольку я не могу для жизни меня выработать способ уменьшить или отключить звук воспроизведения моего приложения.
Я не хочу изменять глобальный том системы только уровень уровня приложения, определенный категорией AVAudioSession
AVAudioSessionCategoryPlayback
.
Кажется, вы можете установить громкость AVAudioPlayer
, но не MPMoviePlayerController
. Я видел другие сообщения здесь, на SO, которые говорят, что просто создайте экземпляр AVAudioPlayer
и установите том, но это просто приводит к сбою моего приложения, и я ожидаю, что это имеет какое-то отношение к тому факту, что я не использую initWithContentsOfURL:error:
или initWithData:error:
и вместо этого используйте `init '.
Любая помощь будет оценена по достоинству.
Ответы
Ответ 1
После разговора с техником Apple выясняется, что с помощью MPMoviePlayerController
невозможно управлять или отключать звук с помощью MPMoviePlayerController
.
Вместо этого вам нужно создать свой собственный контроллер, используя класс AVFoundations AVPlayer
.
Как только вы используете это, нужно создать собственный аудиомикс и установить уровень громкости. Это действительно работает очень хорошо.
Пример кода:
AVURLAsset * asset = [AVURLAsset URLAssetWithURL:[self localMovieURL] options:nil];
NSArray *audioTracks = [asset tracksWithMediaType:AVMediaTypeAudio];
// Mute all the audio tracks
NSMutableArray * 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];
// Create a player item
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];
[playerItem setAudioMix:audioZeroMix]; // Mute the player item
// Create a new Player, and set the player to use the player item
// with the muted audio mix
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
self.mPlayer = player;
[mPlayer play];
Я написал класс замены MPMoviePlayerController
, который добавляет поддержку уровня громкости. Я скоро отправлю в github и добавлю ссылку в этот пост.
Ответ 2
Я знаю, что это старый пост, но мне удалось найти способ успешно управлять объемом элемента управления MPMoviePlayerController в iOS6 и iOS7 с помощью MPVolumeView. Один из них заключается в том, что он не работает в симуляторе, только на физическом устройстве. Чтобы просто контролировать громкость, добавление скрытого MPVolumeView будет работать нормально. Однако, если вы используете скрытый, на дисплее основного тома, отображаемого при изменении громкости с помощью кнопок громкости физического устройства, по-прежнему будет отображаться центральный экран. Если вы хотите предотвратить это, убедитесь, что ваш MPVolumeView не скрыт. Вместо этого вы можете дать ему очень низкую альфа-прозрачность и поместить ее за другие виды, поэтому пользователь не может ее увидеть.
Вот код, который я использовал:
MPVolumeView *volumeView = [[MPVolumeView alloc]initWithFrame:CGRectZero];
[volumeView setShowsVolumeSlider:YES];
[volumeView setShowsRouteButton:NO];
// control must be VISIBLE if you want to prevent default OS volume display
// from appearing when you change the volume level
[volumeView setHidden:NO];
volumeView.alpha = 0.1f;
volumeView.userInteractionEnabled = NO;
// to hide from view just insert behind all other views
[self.view insertSubview:volumeView atIndex:0];
Это позволяет вам управлять громкостью, вызывая: [[MPMusicPlayerController applicationMusicPlayer] setVolume: 0.0];
Но я все еще получал отображение объема собственной ОС в первый раз, когда я попытался изменить громкость - при последующих загрузках он не показывал этот дисплей, поэтому полагая, что это связано со стадией жизненного цикла viewcontroller, Я переместил его из моего метода viewDidLoad в метод viewDidAppear - он сработал - громкость отключена, а внешний вид основного тома не появился, , но Теперь я смог услышать долю секунды аудио до видео начал играть. Таким образом, я подключился к состоянию воспроизведения, изменив делегат MPMoviePlayerController. В viewDidload я добавил:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(videoPlaybackStateDidChange:)
name:MPMoviePlayerPlaybackStateDidChangeNotification object:nil];
И метод обратного вызова делегата:
-(void)videoPlaybackStateDidChange:(NSNotification *)aNotification
{
// Note, this doesn't work in simulator (even in iOS7), only on actual device!
if ([moviePlayerController playbackState] == MPMoviePlaybackStatePlaying)
{
[[MPMusicPlayerController applicationMusicPlayer] setVolume:0.0];
}
}
Это отключило звук видео до его начала воспроизведения, но после просмотраDidLoad в жизненном цикле, поэтому внешний звук OS не отключен.
В моем приложении я загрузил и сохранил текущий уровень громкости перед отключением (с использованием свойства [MPMusicPlayerController applicationMusicPlayer].volume), а затем восстановил том на этом уровне, когда контроллер просмотра был закрыт, что означает, что пользователь не будет знать, что уровень их устройства был изменен и возвращен.
Кроме того, если ваш MPMoviePlayerController использует нестандартный аудиомаршрут в iOS7, вызов [[MPMusicPlayerController applicationMusicPlayer] setVolume: 0.0] может не сработать для вас - в этом случае вы можете прокручивать подзоны вашего элемента управления MPVolumeView до тех пор, пока вы не найти представление, какие подклассы UISlider. Затем вы можете вызвать [sliderView setValue: 0 animated: NO], который должен работать для вас. Этот метод не использует какие-либо частные API Apple, поэтому не следует отклонять ваше приложение. В конце концов, существует так много законных причин, почему вы предлагаете эту функциональность, и это было возможно в iOS6 без необходимости идти на эти длины! Фактически, я был обескуражен, обнаружив, что Apple удалила функциональность, чтобы установить громкость на MPMoviePlayerController в iOS7 в первую очередь. Принудительная миграция на AVPlayer?
Обновление: Мое приложение iPad теперь одобрено с использованием этого метода и находится в прямом эфире в магазине приложений.