Dav*_*eet 6 spotify ios cocoalibspotify-2.0
我想在启用Spotify的应用程序中从一个轨道交叉淡入淡出.这两个曲目都是Spotify曲目,因为一次只有一个数据流可以来自Spotify,我怀疑我需要缓冲(我想我可以提前读取1.5倍的播放速度)第一首曲目的最后几秒,启动流对于音轨2,淡出一个并使用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;
Run Code Online (Sandbox Code Playgroud)
并在
- (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;
Run Code Online (Sandbox Code Playgroud)
并添加了一个基于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);
}
}];
}
Run Code Online (Sandbox Code Playgroud)
这启动了交叉淡入淡出的计时器
crossfadeTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(crossfadeCountdown)userInfo:nil repeats:YES];
并且为了在SPCoreAudioController.m中加载数据后保持第一首曲目播放,我更改了目标缓冲区长度:
static NSTimeInterval const kTargetBufferLength = 20;
Run Code Online (Sandbox Code Playgroud)
并在SPSession.m中:end_of_track(sp_session*session){
我删除了
// sess.playing = NO;
Run Code Online (Sandbox Code Playgroud)
我调用preloadTrackForPlayback:在音轨结束前大约15秒,然后是crossfadeTrack:在10秒之前.
然后设置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];
}
}
Run Code Online (Sandbox Code Playgroud)
我会继续努力,如果我能做得更好就会更新.再次感谢iKenndac的总是现场帮助!
据我所知,没有使用 CocoaLibSpotify 的预先编写的交叉淡入淡出示例。然而,(也许不理想)的游戏计划是:
创建两个独立的音频队列。SPCoreAudioController是音频队列的封装,因此您应该能够实例化其中两个。
正常向一个队列播放音乐。当您接近曲目末尾时,调用SPSession下一preloadTrackForPlayback:callback:首曲目的 方法以使其做好准备。
当播放曲目的所有音频数据都已传递后,SPSession将触发音频委托方法sessionDidEndPlayback:。这意味着所有音频数据均已传送。但是,由于 CocoaLibSpotify 缓冲来自 libspotify 的音频,因此音频停止之前还有一段时间。
此时,开始播放新曲目,但将音频数据转移到第二个音频队列。开始降低第一个队列的音量,同时提高下一个队列的音量。这应该会产生令人满意的交叉淡入淡出效果。
几点提示:
在 中SPCoreAudioController.m,您将找到以下行,它定义了 CocoaLibSpotify 缓冲的音频量(以秒为单位)。如果您想要更大的交叉淡入淡出,则需要增加它。
static NSTimeInterval const kTargetBufferLength = 0.5;
Run Code Online (Sandbox Code Playgroud)由于您以最大 1.5 倍实际播放速度获取音频数据,因此请注意不要在用户刚刚跳到曲目末尾附近时进行 5 秒交叉淡入淡出等操作。您可能没有足够的音频数据来完成它。
好好看看SPPlaybackManager.m。该类是 CocoaLibSpotify 和 Core Audio 之间的接口。它并不太复杂,理解它会让你走得更远。SPCoreAudioController并且SPCircularBuffer几乎都是将音频输入 Core Audio 的实现细节,您不需要了解它们的实现来实现您想要的。
另外,请确保您了解各个代表SPSession的情况。音频传输委托只有一项工作 - 接收音频数据。播放委托获取所有其他播放事件 - 当音频完成传递到音频传递委托时等。没有什么可以阻止一个类同时兼任这两种事件,但在当前实现中,SPPlaybackManager是播放委托,它创建一个实例SPCoreAudioController作为音频交付代表。如果您修改SPPlaybackManager为拥有两个核心音频控制器并交替使用其中一个作为音频传输委托,那么您应该会很顺利。
| 归档时间: |
|
| 查看次数: |
1262 次 |
| 最近记录: |