Open TongQuEdu opened 6 years ago
投屏连接失败了吗?怎么调用的呢?401说明这个服务中没有该名称的动作,action不存在
401问题解决了,新问题是投屏失败,视频投不上去,目前的状态是智能电视上不显示画面。使用AirPlay可以,DLNA不行。(注:电视是海信的) 发现:传输状态CurrentTransportState为STOPPED。 我尝试重新发送Play动作,状态改变为PLAYING,但是电视上还是不能显示画面。请教下是什么原因?
我打印了请求log过程跟你贴上来:
1、设置URI。<NSArrayM 0x608000050c80>(
GDataXMLElement 0x608000050740: {type:1 name:u:SetAVTransportURIResponse xml:"
1、手机端和电视端要保持在同一个wifi网络下才可以投屏,这点你肯定知道的,请检查下。 2、这个库我没有给出调用demo,在这里表示抱歉,后面会加以改进。我简单说明下: UAUPnPController是用来控制DLNA播放的,UAControlDevice是投屏设备model类同时控制Airplay的投屏播放,UAControlManager是两种投屏方式的控制类,所以主要使用UAControlManager来控制投屏播放。这里写的不太好耦合较多,UAControlManager主要实现搜索设备,连接设备并投屏播放,暂停和继续播放,其它像拖拽进度,切换视频资源等没有在这里面实现,需要你自己根据UAUPnPController和UAControlDevice中的方法来实现。主要调用步骤:
(1)[[UAControlManager sharedManager] startSearching],设置delegate (2)实现代理方法,在manager:didFindDevice:这个代理方法里面获取搜索到的投屏设备(如智能电视,小米盒子,天猫魔盒等),放到一个数组里,比如用tableView之类的控件显示 (3)对于Airplay,点击设备后根据index获取设备UAControlDevice的对象,使用[[UAControlManager sharedManager] connectAirPlayDevice: device]方法先连接,然后在manager:didConnectToDevice:代理方法中调用[manager.connectedDevice sendContentWithURL: videoURL]方法进行投屏播放。这里是两步操作
对于DLNA,只需要一步操作,点击设备获取到device之后使用[[UAControlManager sharedManager] connectDLNADevice: device url: videoURL]方法直接传递给它选中的设备和视频地址就可以了。
PS: 如果还是有问题,建议你先看下本仓库说明中最下面的两个链接,第一个是讲的DLNA投屏的协议和使用示例比较详细,第二个是github上一个demo,本仓库这部分代码是在这个demo基础上完成的,实测可用。由于现在手边没有支持DLNA投屏方式的智能设备,所以现在我也无法进行测试,后面我会完善代码。
您说的我都明白的,下面👇是我的demo,流程应该跟您说的一样的,AirPlay投屏可顺利,可就是DLNA的就是死活投不上去,您说测试是可用的,我测试不可用不知道是不是跟电视机型有关系?如果您后续有更新或遇到类似问题,希望你能在issues的主题里回复以下。谢谢!
@interface AirPlayViewController ()<UAControlManagerDelegate,UITableViewDelegate,UITableViewDataSource> @property (nonatomic, strong) NSMutableArray <UAControlDevice >airPlayAry; @property (nonatomic, strong) NSMutableArray <UAControlDevice >dlnaAry; @property (nonatomic, strong) NSDictionary *deviceDict;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@end
@implementation AirPlayViewController
(void)viewDidLoad { [super viewDidLoad];
_airPlayAry = [NSMutableArray array]; _dlnaAry = [NSMutableArray array]; _deviceDict = @{@"airPlay":_airPlayAry, @"dlna":_dlnaAry};
[[UAControlManager sharedManager] startSearching]; [UAControlManager sharedManager].delegate = self; // Do any additional setup after loading the view from its nib. }
(IBAction)play:(UIButton *)sender {
sender.selected = !sender.selected; if (sender.selected) { [[UAControlManager sharedManager] pause]; } else { [[UAControlManager sharedManager] resume]; }
}
(void)manager:(UAControlManager )manager didFindDevice:(UAControlDevice )device { NSLog(@"\n- didFindDevice %@",device.deviceName);
if (device.deviceType == UADeviceTypeAirPlay) { [_airPlayAry addObject:device]; } else { [_dlnaAry addObject:device]; }
[self.tableView reloadData]; }
(void)manager:(UAControlManager )manager didConnectToDevice:(UAControlDevice )device { NSLog(@"\n- didConnectToDevice %@",device); if (device.deviceType == UADeviceTypeAirPlay) { [[UAControlManager sharedManager].connectedDevice sendContentWithURL:@"https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"]; } else { } }
(void)manager:(UAControlManager *)manager didStopSearchingWithServiceCount:(NSInteger)count { NSLog(@"\n- didStopSearchingWithServiceCount %ld",count); }
(void)manager:(UAControlManager *)manager didCompleteActionWithTag:(UAAirPlayActionType)tag { NSLog(@"\n- didCompleteActionWithTag %ld",tag); }
(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return _deviceDict.allValues.count; }
(NSInteger)tableView:(UITableView )tableView numberOfRowsInSection:(NSInteger)section { NSArray ary = _deviceDict.allValues[section]; return ary.count; }
(UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString cellIdentifier = @"cellIdentifier"; UITableViewCell cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; }
NSArray ary = _deviceDict.allValues[indexPath.section]; UAControlDevice model = ary[indexPath.row]; cell.textLabel.text = model.deviceName;
return cell; }
(void)tableView:(UITableView )tableView didSelectRowAtIndexPath:(NSIndexPath )indexPath {
NSArray ary = _deviceDict.allValues[indexPath.section]; UAControlDevice model = ary[indexPath.row]; if (model.deviceType == UADeviceTypeAirPlay) { [[UAControlManager sharedManager] connectAirPlayDevice:model]; } else { [[UAControlManager sharedManager] connectDLNADevice:model url:@"https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"]; } }
(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 20; }
(NSString )tableView:(UITableView )tableView titleForHeaderInSection:(NSInteger)section {
NSString *title = _deviceDict.allKeys[section]; return title; } @end
你们是怎么调用, 求教! 万分感谢
UAUPnPAction.m 这个文件第64行调用错函数了,将'elementWithName'改为'attributeWithName'即可修复DLNA投屏可能出错的问题。
未定义的响应/错误s:Client UPnPError 401 Invalid Action </s:Fault>