目前国内的视频播放器中,支持 DLNA 播放比较好的是:腾讯视频。
刚才反编了一下他们的代码,发现使用了一个开源库,
地址:https://github.com/FuruyamaTakeshi/DLNA
并且在这个库的基础了做了一层封装,包含如下几个类:
DLNAController:
1 @class CGUpnpAvController, CGUpnpAvRenderer, QLUpnpAVVolumeInfo, NSMutableArray, QLUpnpAVPositionInfo, NSString, NSTimer; 2 @protocol DLNAControllerDelegate; 3 4 @interface DLNAController : XXUnknownSuperclass <CGUpnpControlPointDelegate> { 5 @private 6 dispatch_queue_s* _playQueue; // 4 = 0x4 7 dispatch_queue_s* _searchQueue; // 8 = 0x8 8 CGUpnpAvRenderer* _dlnaPlayingRender; // 12 = 0xc 9 CGUpnpAvRenderer* _dlnaSelectedRender; // 16 = 0x10 10 CGUpnpAvController* _upnpAvController; // 20 = 0x14 11 NSMutableArray* _dlnaRenders; // 24 = 0x18 12 NSTimer* _timerLoadInfos; // 28 = 0x1c 13 BOOL _isSettingVolume; // 32 = 0x20 14 BOOL _isSettingSeek; // 33 = 0x21 15 id<DLNAControllerDelegate> delegate; // 36 = 0x24 16 float _trackDuration; // 40 = 0x28 17 float _curPlayTime; // 44 = 0x2c 18 float _volumePercentage; // 48 = 0x30 19 NSString* _curRenderName; // 52 = 0x34 20 unsigned _fileSize; // 56 = 0x38 21 QLUpnpAVPositionInfo* _positionInfo; // 60 = 0x3c 22 QLUpnpAVVolumeInfo* _volumeInfo; // 64 = 0x40 23 NSString* _curTitle; // 68 = 0x44 24 } 25 @property(retain) QLUpnpAVPositionInfo* positionInfo; // G=0x1ecead; S=0x1ecec5; 26 @property(retain) QLUpnpAVVolumeInfo* volumeInfo; // G=0x1ecee9; S=0x1ecf01; 27 @property(readonly, assign) int dlnaRendersCount; // G=0x1eabf5; 28 @property(readonly, assign) float volumePercentage; // G=0x1eae41; 29 @property(readonly, assign) float curPlayTime; // G=0x1ead59; 30 @property(readonly, assign) float trackDuration; // G=0x1eadcd; 31 @property(readonly, assign) NSString* curRenderName; // G=0x1eacc1; 32 @property(copy) NSString* curTitle; // G=0x1ecf25; S=0x1ecf3d; 33 @property(assign) unsigned fileSize; // G=0x1ece81; S=0x1ece95; 34 @property(assign) id<DLNAControllerDelegate> delegate; // G=0x1ece55; S=0x1ece69; 35 +(id)sharedDLNAController; // 0x1ea329 36 -(void)didFindRendersMain:(id)main; // 0x1ecdfd 37 -(void)maitainConnectionMain:(id)main; // 0x1ecdb5 38 -(void)loseConnectionMain:(id)main; // 0x1eccc1 39 -(void)mainPlayStop:(id)stop; // 0x1ecc65 40 -(void)mainPlayFailed:(id)failed; // 0x1ecc1d 41 -(void)mainPlayDown:(id)down; // 0x1ecbc1 42 -(BOOL)setVolume:(float)volume skipIfBusy:(BOOL)busy; // 0x1eca55 43 -(BOOL)seek:(double)seek; // 0x1ec8f9 44 -(BOOL)quit; // 0x1ec719 45 -(BOOL)stop; // 0x1ec5ed 46 -(BOOL)pause; // 0x1ec4d1 47 -(BOOL)play; // 0x1ec341 48 -(BOOL)isPlaying; // 0x1ec305 49 -(void)controlPoint:(id)point deviceInvalid:(id)invalid; // 0x1ec301 50 -(void)controlPoint:(id)point deviceUpdated:(id)updated; // 0x1ec2fd 51 -(void)controlPoint:(id)point deviceRemoved:(id)removed; // 0x1ebfa1 52 -(void)controlPoint:(id)point deviceAdded:(id)added; // 0x1ebc61 53 -(void)searchReaders:(BOOL)readers; // 0x1eb8a9 54 -(void)connection:(id)connection didReceiveResponse:(id)response; // 0x1eb785 55 -(void)connectionDidFinishLoading:(id)connection; // 0x1eb76d 56 -(void)connection:(id)connection didFailWithError:(id)error; // 0x1eb719 57 -(void)playOnThreadWithInfo:(id)info; // 0x1eb4e5 58 -(void)beginPlayDLNAWithUrl:(id)url; // 0x1eb225 59 -(void)playURL:(id)url; // 0x1eafc5 60 -(void)setRenderAtIndex:(int)index; // 0x1eaea5 61 -(id)getRenderAtIndex:(int)index; // 0x1eaafd 62 -(void)loadInfoOfDLNA; // 0x1ea83d 63 -(void)stopTimers; // 0x1ea80d 64 -(void)startTimers; // 0x1ea7ad 65 -(void)clearAllInfos; // 0x1ea76d 66 -(void)clearTimerInfo; // 0x1ea71d 67 -(void)clearPlayInfo; // 0x1ea5e5 68 -(id)init; // 0x1ea539 69 -(void)dealloc; // 0x1ea411 70 @end
DLNAControllerDelegate
1 @protocol DLNAControllerDelegate <NSObject> 2 -(void)dlnaControllerdidStoped:(id)stoped; 3 -(void)dlnaControllerdidMaitainConnection:(id)connection; 4 -(void)dlnaControllerdidLoseConnection:(id)connection; 5 -(void)dlnaControllerdidFailedToPlay:(id)play; 6 -(void)dlnaControllerdidStartToPlay:(id)play; 7 -(void)dlnaController:(id)controller didFindRenders:(id)renders; 8 @end
DLNAModel
1 @protocol DLNAModelDelegate; 2 3 @interface DLNAModel : XXUnknownSuperclass { 4 @private 5 id<DLNAModelDelegate> _delegate; // 4 = 0x4 6 } 7 @property(assign, nonatomic) id<DLNAModelDelegate> delegate; // G=0x1d2409; S=0x1d2419; 8 -(void)request:(id)request didFailLoadWithError:(id)error; // 0x1d23c9 9 -(void)requestDidFinishLoad:(id)request; // 0x1d2045 10 -(void)sendRequestWithVideoID:(id)videoID isPay:(BOOL)pay; // 0x1d1ef5 11 @end
DLNAModelDelegate
@protocol DLNAModelDelegate <NSObject> -(void)DLNAModelDelegateRequestDidFail:(id)dlnamodelDelegateRequest; -(void)DLNAModelDelegateRequestDidSuccess:(id)dlnamodelDelegateRequest urlString:(id)string; @end
DLNAPlayBkgView
@class UIActivityIndicatorView, UILabel; @interface DLNAPlayBkgView : XXUnknownSuperclass { @private UILabel* _tmpLabel; // 48 = 0x30 UIActivityIndicatorView* _tIndicator; // 52 = 0x34 } @property(retain, nonatomic) UILabel* tmpLabel; // G=0x1d0c25; S=0x1d0c35; @property(retain, nonatomic) UIActivityIndicatorView* tIndicator; // G=0x1d0c59; S=0x1d0c69; -(void)setLableTip:(id)tip showActivity:(BOOL)activity; // 0x1d0a5d -(id)initWithFrame:(CGRect)frame; // 0x1d06c1 -(void)dealloc; // 0x1d0669 @end
DLNASelectorView
@class UITableView, UIView; @protocol DLNASelectorViewDelegate; @interface DLNASelectorView : XXUnknownSuperclass <UITableViewDataSource, UITableViewDelegate> { @private UIView* _dlnaSearchingView; // 48 = 0x30 UITableView* _dlnaTableView; // 52 = 0x34 id<DLNASelectorViewDelegate> _delegate; // 56 = 0x38 UIView* _tContentView; // 60 = 0x3c UIView* _noneDLNATipView; // 64 = 0x40 } @property(retain, nonatomic) UIView* dlnaSearchingView; // G=0x1d16c9; S=0x1d1e35; @property(retain, nonatomic) UITableView* dlnaTableView; // G=0x1d15dd; S=0x1d1e59; @property(retain, nonatomic) UIView* noneDLNATipView; // G=0x1d12cd; S=0x1d1ed1; @property(retain, nonatomic) UIView* tContentView; // G=0x1d1e9d; S=0x1d1ead; @property(assign, nonatomic) id<DLNASelectorViewDelegate> delegate; // G=0x1d1e7d; S=0x1d1e8d; -(void)tableView:(id)view didSelectRowAtIndexPath:(id)indexPath; // 0x1d1dc1 -(int)tableView:(id)view numberOfRowsInSection:(int)section; // 0x1d1d8d -(id)tableView:(id)view cellForRowAtIndexPath:(id)indexPath; // 0x1d1bf1 -(void)dlnaCloseDown:(id)down; // 0x1d1bc5 -(void)dlnaRefreshDown:(id)down; // 0x1d1b15 -(void)showSearchView; // 0x1d1ab9 -(void)refreshSelectorTable; // 0x1d18dd -(id)initWithFrame:(CGRect)frame; // 0x1d0d11 -(void)dealloc; // 0x1d0c91 @end
@protocol DLNASelectorViewDelegate <NSObject> -(void)DLNASelectorViewSelectedRender:(id)render; -(void)DLNASelectorViewWillClose:(id)dlnaselectorView; @end
QLUpnpAVPositionInfo:
@class CGUpnpAction; @interface QLUpnpAVPositionInfo : XXUnknownSuperclass { @private float _trackDuration; // 4 = 0x4 float _absTime; // 8 = 0x8 float _relTime; // 12 = 0xc CGUpnpAction* _upnpAction; // 16 = 0x10 } @property(retain, nonatomic) CGUpnpAction* upnpAction; // G=0x1f1eb5; S=0x1f1ec5; @property(readonly, assign, nonatomic) float relTime; // G=0x1f1ea5; @property(readonly, assign, nonatomic) float absTime; // G=0x1f1e95; @property(readonly, assign, nonatomic) float trackDuration; // G=0x1f1e85; -(void)dealloc; // 0x1f1e41 -(id)initWithAction:(id)action; // 0x1f1d65 @end
QLUpnpAVVolumeInfo
@class CGUpnpAction; @interface QLUpnpAVVolumeInfo : XXUnknownSuperclass { @private float _currentVolumePercentage; // 4 = 0x4 CGUpnpAction* _upnpAction; // 8 = 0x8 } @property(retain, nonatomic) CGUpnpAction* upnpAction; // G=0x1ed05d; S=0x1ed06d; @property(readonly, assign, nonatomic) float currentVolumePercentage; // G=0x1ed04d; -(void)dealloc; // 0x1ed009 -(id)initWithAction:(id)action; // 0x1ecf61 @end
找时间阅读下汇编代码,写出一个开源版本。^_^