Възпроизвеждане на звук само веднъж, условие

Опитвам се да възпроизвеждам звук само когато 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;
    }

и се възпроизвежда, но само началото, една секунда и след това започва отново и отново, без да завърши целия звук.

Предполагам, че това се дължи на angleDegrees, който се променя през цялото време. Някаква идея как може да се реши това, моля?


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