iOS在线收音机流媒体问题

12

我需要创建一款提供在线无线电流媒体(icecast)服务的应用程序,最好使用.ogg格式。 因此我有以下问题:

  1. 如何播放.ogg格式音频流?是否有任何支持的类?因为我找不到任何支持它的类,所以我认为除了使用多个位运算操作外,没有其他方法,这可能需要使用到 CFNetwork, CoreAudio, AudioToolbox等等。(我不考虑cocos2d,因为那太荒谬了)我错了吗?
  2. 目前我正在播放mp3流(对我来说没有.ogg的可能性)。我尝试使用AVPlayerMPMovieMediaController由MattGallagher和DigitalDJ开发的AudioSreaming库,但是这些解决方案都不能提供元数据访问。

对于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 count始终为0,没有歌曲\艺术家\任何元数据。
对于MPMovieMediaController也是如此,metadataUpdate从未被调用。

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] 总是 nil。

我已经尝试了

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

但是仍然无法获取当前播放曲目信息,该信息只能在 SHOUTcast 应用程序 中获取,如下所示:

第一条 Metadata = 'StreamTitle=',

第二条 metadata = ''bitrate = '128000'
(所以我想我必须处理来自http头响应的字节或类似的东西?但它是 shoutcast 元数据,我的 radiostream 是 icecast。没有主意)
我会非常感激任何帮助!


2
是的,我看到了 CocoaWithLove 的“mp3流媒体”文章系列和HTTP Live Streaming概述。 - Aft3rmath
关于元数据...这个问题每周至少被回答一次。搜索一下吧。Icecast被构建为与SHOUTcast兼容,并以相同的方式返回元数据。 - Brad
我的意思是你的SHOUTcast/Icecast服务器。它没有元数据要发送。https://dev59.com/V2445IYBdhLWcg3wWI6L#4914538 http://stackoverflow.com/questions/3696208/parsing-shoutcast-server-information-table-with-javascript/4069719#4069719 https://dev59.com/FV3Va4cB1Zd3GeqPENRs#8342918 - Brad
你试过这个吗?https://github.com/muhku/FreeStreamer 它帮助我流式传输我的Shoutcast,但我还没有任何OGG文件来尝试并查看它是否可用。 - Neeku
我做了这个:音频流使用AVPlayer(mp3,临时解决方案),元数据则通过AudioStreamer库单独解析(也是临时的)。 - Aft3rmath
显示剩余8条评论
3个回答

6
Icecast和Shoutcast彼此兼容。它们的区别在于它们响应HTTP GET请求的方式。当您向Icecast服务器发送HTTP GET请求时,它会回复一个HTTP 200 OK响应。响应头将包含icy-br、icy-metaint、icy-name、icy-genre和icy-url键的值。
当您向Shoutcast服务器发送HTTP GET请求时,它将以ICY 200 OK响应进行响应。在这种情况下,您需要解析响应数据,因为元数据不会在响应头中提供。
最重要的元数据键是icy-metaint键。该值将告诉您流中元数据发送的频率。有关解析此元数据的更多信息,请查看此网站:Shoutcast Metadata Protocol 要播放ogg流,您需要使用开源FFmpeg库。该库可以编译为iOS平台,并用于连接和解码ogg流。

3

要播放一个ogg格式的音频流,您需要提供一个编解码器。iOS没有本地支持ogg格式的功能。


3

我认为首先要做的事情是通过设置请求头来“订购”元数据:

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

在我的情况下,我在Matt Galagher的音频流中添加了这行代码。结果是,当流正在播放时,我实际上可以听到元数据,因为它包含在流数据中。下一步是过滤掉元数据并解释它。为了实现这一点,所有必要的信息已经在这里提到。
祝你好运!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接