我想在支持 Spotify 的应用程序中从一首曲目交叉淡入到下一首曲目。两个曲目都是 Spotify 曲目,由于一次只能来自 Spotify 的一个数据流,我怀疑我需要缓冲(我想我可以提前 1.5 倍播放速度)第一首曲目的最后几秒钟,开始流对于轨道二,使用 AudioUnit 淡出一并淡入二。
我已经查看了示例应用程序:Viva - https://github.com/iKenndac/Viva SimplePlayer with EQ - https://github.com/iKenndac/SimplePlayer-with-EQ并试图让我的想法围绕 SPCircularBuffer,但是我仍然需要帮助。有人可以给我指出另一个例子或帮助指出一个轨道交叉淡入淡出的游戏计划吗?
更新:感谢 iKenndac,我大约 95% 在那里。我将发布到目前为止的内容:
在 SPPlaybackManager.m 中:initWithPlaybackSession:(SPSession *)aSession {
添加:
self.audioController2 = [[SPCoreAudioController alloc] init];
self.audioController2.delegate = self;
并且在
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
...
self.audioController.audioOutputEnabled = self.playbackSession.isPlaying;
// for crossfade, add
self.audioController2.audioOutputEnabled = self.playbackSession.isPlaying;
并添加了基于 playTrack 的新方法
-(void)crossfadeTrack:(SPTrack *)aTrack callback:(SPErrorableOperationCallback)block {
// switch audiocontroller from current to other
if (self.playbackSession.audioDeliveryDelegate == self.audioController)
{
self.playbackSession.audioDeliveryDelegate = self.audioController2;
self.audioController2.delegate = self;
self.audioController.delegate = nil;
}
else
{
self.playbackSession.audioDeliveryDelegate = self.audioController;
self.audioController.delegate = self;
self.audioController2.delegate = nil;
}
if (aTrack.availability != SP_TRACK_AVAILABILITY_AVAILABLE) {
if (block) block([NSError spotifyErrorWithCode:SP_ERROR_TRACK_NOT_PLAYABLE]);
self.currentTrack = nil;
}
self.currentTrack = aTrack;
self.trackPosition = 0.0;
[self.playbackSession playTrack:self.currentTrack callback:^(NSError *error) {
if (!error)
self.playbackSession.playing = YES;
else
self.currentTrack = nil;
if (block) {
block(error);
}
}];
}
这将启动交叉淡入淡出的计时器
crossfadeTimer = [NSTimer scheduledTimerWithTimeInterval: 0.5 目标:自我选择器:@selector (crossfadeCountdown) userInfo: nil repeats: YES];
为了在数据加载到 SPCoreAudioController.m 后继续播放第一首曲目,我更改了目标缓冲区长度:
static NSTimeInterval const kTargetBufferLength = 20;
在 SPSession.m 中: end_of_track(sp_session *session) {
我删除了
// sess.playing = NO;
我在曲目结束前约 15 秒调用 preloadTrackForPlayback:,然后在 10 秒前调用 crossfadeTrack:。
然后设置 crossfadeCountdownTime = [你想要交叉淡入淡出的秒数]*2;
我在交叉淡入淡出上淡化音量:
- (void) crossfadeCountdown
{
[UIAppDelegate.playbackSPManager setVolume:(1- (((float)crossfadeCountdownTime/ (thisCrossfadeSeconds*2.0)) *0.2) )];
crossfadeCountdownTime -= 0.5;
if (crossfadeCountdownTime == 1.0)
{
NSLog(@"Crossfade countdown done");
crossfadeCountdownTime = 0;
[crossfadeTimer invalidate];
crossfadeTimer = nil;
[UIAppDelegate.playbackSPManager setVolume:1.0];
}
}
我会继续努力,如果我能做得更好,我会更新。再次感谢 iKendac 的及时帮助!