12

我必须创建提供在线广播流(icecast)的应用程序,最好是 .ogg 格式。所以我有下一个问题:

  1. 如何播放.ogg格式的音频流?有支持的类吗?因为我找不到任何东西,所以我认为没有使用CFNetwork,CoreAudio等 的许多按位运算是不可能的AudioToolbox(我不看 cocos2d,因为它很荒谬)我错了吗?
  2. 我现在正在播放 mp3 流(.ogg 对我来说不可能)。我尝试使用MattGallagher 和 DigitalDJ 的 AudioSreaming 库AVPlayer但这些解决方案都不能为我提供元数​​据访问。MPMovieMediaController

对于 AVPlayer:

   -(void)playButtonPressed:(id)sender
    {
        NSURL *grindURL = [NSURL URLWithString:@"http://radio.goha.ru:8000/grind.fm"];
                    grindFMPlayer = [[AVPlayer alloc] initWithURL:grindURL];
                    [grindFMPlayer.currentItem addObserver:self forKeyPath:@"status" options:0 context:nil]; 
                    AVPlayerItem *item = grindFMPlayer.currentItem;
                    [grindFMPlayer play];
    }

-(void)stopButtonPressed:(id)sender
{
            AVURLAsset *ass = grindFMPlayer.currentItem.asset;
            NSArray *arr = [ass commonMetadata];
            NSArray *it_meta = [grindFMPlayer.currentItem timedMetadata];
            [grindFMPlayer pause];
}

arrit_meta 计数始终为 0,没有歌曲\艺术家\任何元数据。
相同的MPMovieMediaController,元数据更新从未调用

streamAudioPlayer = [[MPMoviePlayerController alloc] 
                                                   initWithContentURL:[NSURL URLWithString:@"http://radio.goha.ru:8000/grind.fm"];
                streamAudioPlayer.movieSourceType = MPMovieSourceTypeStreaming;
                [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(MetadataUpdate:) name:MPMoviePlayerTimedMetadataUpdatedNotification object:nil];
[streamAudioPlayer play];

并在停止按钮方法中:

timedMeta = [streamAudioPlayer timedMetadata];
            if ([streamAudioPlayer timedMetadata]!=nil && [[streamAudioPlayer timedMetadata] count] > 0) 
            {
                NSLog(@"metadata count = %d", [[streamAudioPlayer timedMetadata] count]);
                for (MPTimedMetadata *metadata in [streamAudioPlayer timedMetadata]) 
                {
                    NSLog(@"description %@", metadata.allMetadata);
                    if ([[metadata.allMetadata valueForKey:@"key"] isEqualToString:@"title"]) 
                    {
                        NSString *text = [metadata.allMetadata valueForKey:@"value"];
                        NSString* filename = text;
                    }
                }
            }

[streamAudioPlayer timedMetadata]总是零。

我试过了

这 2 个项目用于shoutcast 和icecast - http://www.mikejablonski.org/2009/04/17/reading-shoutcast-metadata-from-a-stream/

但是仍然没有运气获得当前的播放曲目信息,只能在SHOUTcast 应用程序中获取

第一 Metadata = 'StreamTitle='

第二 metadata = ''bitrate = '128000'
(所以我认为我必须处理来自http标头响应或类似内容的字节?但是 wtf,它是广播元数据,但我的无线电流是 icecast。不知道)
我将不胜感激任何帮助!

4

3 回答 3

6

Icecast 和 Shoutcast 相互兼容。不同之处在于它们响应 HTTP GET 请求的方式。当您向 Icecast 服务器发送 HTTP GET 请求时,它会回复 HTTP 200 OK 响应。响应标头将包含 icy-br、icy-mettaint、icy-name、icy-genre 和 icy-url 键的值。

当您向 Shoutcast 服务器发送 HTTP GET 请求时,它将以 ICY 200 OK 响应进行响应。在这种情况下,您必须解析响应数据,因为元数据在响应标头中不可用。

最重要的元数据键是 icy-metaint 键。该值将告诉您元数据在流中发送的频率。有关解析此元数据的更多信息,请查看此网站:Shoutcast 元数据协议

要播放 ogg 流,您需要使用开源 FFmpeg 库。这个库可以为 iOS 平台编译并用于连接和解码 ogg 流。

于 2012-04-10T12:52:21.600 回答
3

要播放 ogg 格式的音频流,您需要提供编解码器。iOS 没有对 ogg 格式的原生支持

于 2012-07-11T17:43:51.623 回答
3

我认为首先要做的是通过设置请求标头来“排序”元数据:

CFHTTPMessageSetHeaderFieldValue(message, CFSTR("Icy-MetaData"), CFSTR("1"));

就我而言,我将此行添加到 Matt Galaghers 的音频流媒体。结果是当流播放时我实际上可以听到元数据,因为它包含在流数据中。下一步是过滤元数据并对其进行解释。为了实现这一点,这里已经提到了所有必要的信息。

祝你好运!

于 2013-03-15T11:11:17.187 回答