سؤال

وأنا باستخدام AVAudioPlayer لتشغيل الموسيقى في بلدي التطبيق فون.

في فئة التي كتبت لدي مجموعة التي تحتوي على الأعداد الصحيحة تصاعدي عشوائية. (2، 4، 9، 17، 18، 20، ...) وتمثل هذه الأعداد الصحيحة مرات في الأغنية التي ينبغي أن يحدث حدث معين. لذلك إذا كنت تأخذ مجموعة المذكورة أعلاه، بعد 2 ثانية من اللعب أغنية، يجب أن يتم استدعاء بعض الطرق. بعد 4 ثوان، ينبغي أن تسمى طريقة أخرى. وهلم جرا.

ولقد حاولت استخدام NSTimer يردد:

NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerTick) userInfo:nil repeats:YES];

وفي كل مرة انها تطلق، فإنه يتحقق ما إذا كانت قيمة Audioplayer ومن arrayindex الحالية هي نفسها:

- (void) timerTick {
   if([[myArray objectAtIndex:currentIndex] intValue] == (int)(player.currentTime)) {
   //here the event-method is called
   currentIndex++;
   }
}

وهذا الرمز يعمل فعلا، ولكن فقط لبعض الوقت. بعد ذلك بعض الوقت، myTimer والموقت الذي يتحكم في musicplayer تكون متزامنة. لذلك يفتقد عنصر myArray ويبدأ حلقة لا نهائية. أنا لا أعرف بالضبط لماذا يحصلون على متزامنة، ولكن أعتقد أنه يمكن أن يكون ذلك بسبب لا يتم بدء الموقت واللاعب في نفس الوقت بالضبط أو ربما بسبب أداء قصيرة يتخلف.

وأعتقد أن لدينا لهذا النهج بطريقة مختلفة تماما. هل الرئيسية القيمة بملاحظة طريقة للقيام بذلك؟ بوسعي أن أضيف صفي بصفة مراقب إلى كائن لاعب، بحيث يحصل على إخطار عندما يتغير قيمة player.currentTime. ولكن هذا من شأنه أن يسبب الكثير من الإخطارات إلى أن ترسل، وأعتقد أنه سيكون سيئا حقا للأداء.

وأي مساعدة بتقدير كبير!

هل كانت مفيدة؟

المحلول

طيب هنا هو بلدي الحل: لقد وجدت التطبيق مفتوح المصدر أن يفعل تقريبا نفس الشيء بلدي التطبيق يجب القيام به، والذي ساعدني كثيرا. انا ذاهب الى العصا مع رمز لدي بالفعل، مع قليل من التعديل يجب أن تكون دقيقة بما فيه الكفاية لأغراض بلدي. ومن هنا:

currentIndex = 0;
myTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(timerTick) userInfo:nil repeats:YES];


- (void) timerTick {
 if(timerRunning){


     if([[myArray objectAtIndex:currentIndex] intValue] <= (int)(player.currentTime*100)) { 
         //some event code
         currentIndex++;
     }
 }
}

وهذا التغيير المهم هو من == إلى <= في الشرط إذا. عندما يحصل غير متزامن ويفتقد عنصر myArray، يتم تصحيح الخطأ مائة القادمة من الثانية. هذا امر جيد بما فيه الكفاية.

وشكرا لمساعدتكم!

نصائح أخرى

ويمكن أن يكون هذا توقيت غير معقول على وفاق، ولكن التعليمات البرمجية لا يستغرق سوى لفترة طويلة لتنفيذ (أي: أطول ثم 1 ثانية).

ويمكن أن لا مجرد استخدام جهاز ضبط الوقت من musicplayer، وتفرخ موضوع في كل مرة يجب أن يحدث حدث؟ بهذه الطريقة الموقت يبقى دون انقطاع، وسوف الخيط الخاص بك تفعل ما يتعين عليها القيام به (دعنا نقول الاشياء الثقيلة).

إذا Reall في ذ بحاجة الى عامين توقيت، وأنا أعتقد أن إنشاء المواضيع الأساسية التي تحافظ على تلك توقيت اثنين متزامنة، ولكن أعتقد أن كنت طالبا للمشكلة هناك ..

وتزامن العالم الحقيقي مع الموسيقى من الصعب جدا لأنه يمكن للمستخدمين يلاحظ سوء المصاحبة لمجرد العاشرة من الثانية أو أقل. قد تجد أن AVAudioPlayer هو بسيط مقابل ما تحتاجه. قد يكون لديك للسيطرة على معدل الموسيقى يلعب باستخدام <لأ href = "http://developer.apple.com/iphone/library/documentation/MusicAudio/Conceptual/AudioQueueProgrammingGuide/index.html#//apple_ref/doc/uid/ TP40005343 "يختلط =" نوفولو noreferrer "> AudioQueueServices بحيث يمكنك مزامنة الموسيقى إلى رمز بدلا من العكس. تستطيع أن ترى الوقت لاطلاق النار التعليمات البرمجية الخروج ثم قم بتشغيل الطرق أمام الموسيقى تلعب في الواقع. فعلت بمهارة وهذا من شأنه مزامنة الموسيقى أكثر من مرة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top