流媒件应用FreeStreamer 学习2

  在网上找了一个mp3的链接http://zhangmenshiting.baidu.com/data2/music/114893270/114783086136800128.mp3?xcode=0e98379e5bedd50a235113068f90fe2161924f83c72cae5b

添加到列表中,可以正常播放.

查看代码中类的结构和方法的调用,记录如下:

#pragma mark  FSAudioController
/**
 * FSAudioController is functionally equivalent to FSAudioStream with
 * one addition: it can be directly fed with a playlist (PLS, M3U) URL
 * or an RSS podcast feed. It determines the content type and forms
 * a playlist for playback.
 *
 * Do not use this class but FSAudioStream, if you already know the content type
 * of the URL. Using this class will generate more traffic, as the
 * content type is checked for each URL.
 */
@interface FSAudioController : NSObject {
    NSString *_url;
    FSAudioStream *_audioStream;
    
    BOOL _readyToPlay;
    
    FSCheckContentTypeRequest *_checkContentTypeRequest;
    FSParsePlaylistRequest *_parsePlaylistRequest;
    FSParseRssPodcastFeedRequest *_parseRssPodcastFeedRequest;
}
@end

#pragma mark FSAudioStream
/**
 * FSAudioStream is a class for streaming audio files from an URL.
 * It must be directly fed with an URL, which contains audio. That is,
 * playlists or other non-audio formats yield an error.
 *
 * To start playback, the stream must be either initialized with an URL
 * or the playback URL can be set with the url property. The playback
 * is started with the play method. It is possible to pause or stop
 * the stream with the respective methods.
 *
 * Non-continuous streams (audio streams with a known duration) can be
 * seeked with the seekToPosition method.
 */
@interface FSAudioStream : NSObject {
    FSAudioStreamPrivate *_private;
}
@end
/*
 * ===============================================================
 * FSAudioStream private implementation
 * ===============================================================
 */
#pragma mark FSAudioStreamPrivate
@interface FSAudioStreamPrivate : NSObject {
    astreamer::Audio_Stream *_audioStream;
    NSURL *_url;
    BOOL _strictContentTypeChecking;
    AudioStreamStateObserver *_observer;
    BOOL _wasInterrupted;
    BOOL _wasDisconnected;
    NSString *_defaultContentType;
    Reachability *_reachability;
#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000)
    UIBackgroundTaskIdentifier _backgroundTask;
#endif
}
@end

- (IBAction)playFromUrl:(id)sender
{
    self.audioController.url = url;//设置 FSAudioController 的 _url属性 和 FSAudioStream中FSAudioStreamPrivate的_url属性
    [self.audioController play]; //self.audioController 调用的是单例方法,返回一个 FSAudioController对象
    {
        @synchronized (self)//@synchronized 的作用是创建一个互斥锁,保证此时没有其它线程对self(即audioController)对象进行修改。
        _audioStream.url = playlistItem.nsURL; // 设置 _audioStream 的url,FSAudioController在init中会申请_audioStream,  FSAudioStream *_audioStream;
        [self.audioStream play]; FSAudioStream.mm
        {
            [_private play]; //FSAudioStream.mm   FSAudioStreamPrivate *_private;
            {
                _audioStream->open(); // FSAudioStream.mm 中调用, astreamer::Audio_Stream *_audioStream;
                {
                    m_httpStream->open();//audio_stream.cpp 中调用,  如果成果,设置m_httpStreamRunning = true; HTTP_Stream *m_httpStream;
                     -->
                        {
                            HTTP_Stream_Position position;
                            position.start = 0;
                            position.end = 0;
                            
                            m_contentLength = 0;
                            #ifdef INCLUDE_ID3TAG_SUPPORT
                            m_id3Parser->reset();
                            #endif
                            return open(position);
                                    {
                                        m_readStream = createReadStream(m_url);//从url中获取stream
                                        {
                                            CFHTTPMessageCreateRequest(kCFAllocatorDefault, httpRequestMethod, url, kCFHTTPVersion1_1);
                                            readStream = CFReadStreamCreateForStreamedHTTPRequest(kCFAllocatorDefault, request, 0);
                                            
                                            CFReadStreamSetProperty(readStream,
                                                                    kCFStreamPropertyHTTPShouldAutoredirect,
                                                                    kCFBooleanTrue);
                                            
                                            proxySettings = CFNetworkCopySystemProxySettings();
                                            CFReadStreamSetProperty(readStream, kCFStreamPropertyHTTPProxy, proxySettings);
                                        }
                                        
                                        CFReadStreamSetClient(m_readStream, kCFStreamEventHasBytesAvailable |
                                                              kCFStreamEventEndEncountered |
                                                              kCFStreamEventErrorOccurred, readCallBack, &CTX);//设置客户端,并使用readCallBack方法 监听事件
                                        
                                        setScheduledInRunLoop(true);
                                        CFReadStreamOpen(m_readStream);//Opens a stream for reading
                                        
                                    }
                            
                        }
                    
                }
                
                [_reachability startNotifier]; //跟在_audioStream->open();后面  用来监控网络
                
            }
            
        }
        
    }

}

 

内部的一些细节和流程还需要进一步学习.

 

 

posted @ 2014-02-25 19:03  米粥米  阅读(2015)  评论(0编辑  收藏  举报