Воспроизведение звука только один раз, условие

Я пытаюсь воспроизвести звук только тогда, когда у моего iphone есть склонность. Я делаю это :

- (void)viewDidLoad {
    [super viewDidLoad];
    self.playing = NO;

    deviceQueue = [[NSOperationQueue alloc] init];
    motionManager = [[CMMotionManager alloc] init];
    motionManager.deviceMotionUpdateInterval = 5.0 / 60.0;

    [motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryZVertical
                                                       toQueue:deviceQueue
                                                   withHandler:^(CMDeviceMotion *motion, NSError *error)
     {
         [[NSOperationQueue mainQueue] addOperationWithBlock:^{
             CGFloat x = motion.gravity.x;
             CGFloat y = motion.gravity.y;
             CGFloat z = motion.gravity.z;

             CGFloat angle = atan2(y, x) + M_PI_2;           // in radians
             CGFloat angleDegrees = angle * 180.0f / M_PI;


              CGFloat r = sqrtf(x*x + y*y + z*z);
             CGFloat tiltForwardBackward = acosf(z/r) * 180.0f / M_PI - 90.0f;




             CMMotionManager* motionManager = [[CMMotionManager alloc] init];
             [motionManager startAccelerometerUpdates];
             CMAccelerometerData* data = [motionManager accelerometerData];
             while ( data.acceleration.x == 0 )
             {
                 data = [motionManager accelerometerData];
             }
             NSLog(@"x = %f, y = %f, z = %f.", data.acceleration.x, data.acceleration.y, data.acceleration.z);

             NSLog(@"angleDegrees = %f, anglee = %f", angleDegrees, angle);
             NSString *soundPath =[[NSBundle mainBundle] pathForResource:@"End-clap" ofType:@"mp3"];
             NSURL *soundURL = [NSURL fileURLWithPath:soundPath];

             NSError *error = nil;
             _audioPlayer4 = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:&error];
             _audioPlayer4.delegate =self;

             if (angleDegrees<180 && angleDegrees>0) {
                 self.guessImg.image=[UIImage imageNamed:@"guessit-Recovered.png"];
                 self.wordLabel.text=@"Justin Bieber";
                             }
           else
             {
             self.wordLabel.text=@"Place on Forehead";

                 if ([self.wordLabel.text isEqualToString:@"Place on Forehead"]) {
                     if(_playing)
                     {


                         _audioPlayer4.numberOfLoops=1;
                         self.wordLabel.text=@"Justin";
                         [_audioPlayer4 play];
                         self.playing=YES;}


                 }


             }

         }];
     }];


}


    - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
    {
        NSLog(@"playing has finished");
        self.playing = NO;
    }

и это играет, но только начало, одну секунду, а затем начать снова и снова, не докончив весь звук.

Я предполагаю, что это из-за угла, который постоянно меняется. Любая идея, как это решить, пожалуйста?


person Adina Marin    schedule 22.07.2015    source источник
comment
Хм, ваш код выглядит нормально для меня - я не понимаю, почему это происходит, если только [AVAudioPlayer playing] не лжет. Добавьте запись в этой области.   -  person trojanfoe    schedule 22.07.2015
comment
В каком методе находится этот код? Как он срабатывает? При смене ориентации?   -  person Quentin Hayot    schedule 22.07.2015
comment
в viewDidLoad , yes.on изменение ориентации   -  person Adina Marin    schedule 22.07.2015


Ответы (2)


Вы можете настроить BOOL, чтобы указать, что проигрыватель играет, и использовать обратный вызов делегата, обозначающий остановку проигрывателя.

@property(atomic) BOOL playing;

После выполнения первого условия if устанавливается значение YES.

Согласно документации Apple по свойству playing:

Не опрашивайте это свойство, чтобы определить, когда воспроизведение завершено, вместо этого реализуйте указанный метод делегата.

Вместо этого мы полагаемся на следующий метод делегата:

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
    NSLog(@"playing has finished");
    self.playing = NO;
}

Чтобы получить обратный вызов, нам нужно установить себя как delegate:

_audioPlayer4 = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:&error];
_audioPlayer4.delegate = self;

Наконец, мы можем заменить ваш внутренний if на:

if(!playing)
{
     self.playing = YES;
     NSString *soundPath =[[NSBundle mainBundle] pathForResource:@"End-clap" ofType:@"mp3"];
     NSURL *soundURL = [NSURL fileURLWithPath:soundPath];

     .......

    [_audioPlayer4 play];
} 

И в viewDidLoad сначала установите для свойства значение NO:

self.playing = NO;

Приложение:

Убедитесь, что ваш контроллер также поддерживает этот протокол.

i.e.,

@interface yourViewController : UIViewController <AVAudioPlayerDelegate>
person Unheilig    schedule 22.07.2015
comment
audioPlayerDidFinishPlaying не вызывается. Я установил делегата и принял протокол :( - person Adina Marin; 22.07.2015
comment
я установил его в начале viewDidLoad. и да, звук играет, но та же проблема. - person Adina Marin; 22.07.2015
comment
Я обновляю свой вопрос. Пожалуйста, взгляните . Я очень ценю вашу помощь. Идея заключается в том, что когда телефон наклонен лицом к небу, чтобы воспроизвести звук, а когда он наклонен лицом к полу, другой звук. - person Adina Marin; 22.07.2015

Потому что angleDegrees все время меняется. поэтому вы должны установить состояние, указывающее, что звук воспроизводится. если он воспроизводится, вы не сможете воспроизвести его снова, пока он не закончится.

person jinhua liao    schedule 22.07.2015
comment
Я вижу, что вы уже проверили состояние воспроизведения аудиоплеера. возможно, вы можете распечатать какой-нибудь журнал, чтобы увидеть результат условия if(!_audioPlayer4.playing). вы должны выяснить, почему это ложно при воспроизведении звука - person jinhua liao; 22.07.2015