目前國內的視頻播放器中,支持 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
找時間閱讀下匯編代碼,給出他們實現的偽代碼。