发现:https://blog.csdn.net/sinat_33859977/article/details/113567847
向固定地址端口发送查询信息
QHostAddress groupAddress;
QUdpSocket *socket;
{
groupAddress = QHostAddress("239.255.255.250");
socket = new QUdpSocket(this);
auto ok = socket->bind(QHostAddress::AnyIPv4, 2068, QUdpSocket::ShareAddress);
connect(socket, SIGNAL(readyRead()), this, SLOT(readMsg()));
ok = socket->joinMulticastGroup(groupAddress);
}
void MainWindow::on_pushButton_discover_clicked()
{
QByteArray BA("M-SEARCH * HTTP/1.1\r\n"
"HOST: 239.255.255.250:1900\r\n"
"ST: urn:schemas-upnp-org:service:AVTransport:1\r\n" //投屏
"MAN: \"ssdp:discover\"\r\n"
"MX: 3\r\n"
"\r\n");
auto writeOk = socket->writeDatagram(BA.data(), groupAddress, 1900);
}
void MainWindow::readMsg()
{
while (socket->hasPendingDatagrams()) {
QByteArray reply;
reply.resize(socket->pendingDatagramSize());
socket->readDatagram(reply.data(), reply.size());
qDebug() << c;
qDebug() << reply.data();
}
每一个设备返回的信息
HTTP/1.1 200 OK
USN: uuid:8fa440b3-f312-4415-8640-f790a3845fcf::urn:schemas-upnp-org:service:AVTransport:1
LOCATION: http://192.168.2.104:1068/description.xml
ST: urn:schemas-upnp-org:service:AVTransport:1
EXT:
SERVER: Linux/5.10.50-amd64-desktop UPnP/1.0 Macast/0.6
CACHE-CONTROL: max-age=66
DATE: Sat, 11 Sep 2021 11:49:18 GMT
打开 http://192.168.2.104:1068/description.xml,可以看到详情
1
0
urn:schemas-upnp-org:device:MediaRenderer:1
uuid:8fa440b3-f312-4415-8640-f790a3845fcf
Macast(sonichy-PC)
xfangfang
https://github.com/xfangfang
AVTransport Media Renderer
Macast
0.6
https://xfangfang.github.io/Macast
DMR-1.50
urn:schemas-upnp-org:service:AVTransport:1
urn:upnp-org:serviceId:AVTransport
AVTransport/action
AVTransport/event
dlna/AVTransport.xml
urn:schemas-upnp-org:service:RenderingControl:1
urn:upnp-org:serviceId:RenderingControl
RenderingControl/action
RenderingControl/event
dlna/RenderingControl.xml
urn:schemas-upnp-org:service:ConnectionManager:1
urn:upnp-org:serviceId:ConnectionManager
ConnectionManager/action
ConnectionManager/event
dlna/ConnectionManager.xml
如何推送网址就比较难了,没人讲清楚,直到找到这个项目:
https://github.com/sYCH3L/TwitchTVDLNAPlayer/blob/master/dlnaclient.cpp#L111
在 UploadFileToPlay 的最后,增加几句,把请求内容写入文件,方便查看究竟写了些什么:
QString DLNAClient::UploadFileToPlay(QString ControlURL, QString UrlToPlay)
{
//Later we will send a message to the DLNA server to start the file playing
QString XML = XMLHead;
XML += "\n";
XML += "0 \n";
XML += "" + UrlToPlay.replace(" ", "%20") + " \n";
XML += "\n" + Desc() + " \n";
XML += " \n";
XML += XMLFoot + "\n";
QString Request = HelperDLNA::MakeRequest("POST", ControlURL, XML.length(), "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI", ip, StrPort) + XML;
qDebug() << Request;
QFile file("request.txt");
if (file.open(QFile::WriteOnly)) {
file.write(Request.toUtf8());
file.close();
}
return HelperDLNA::makeSocketGetReply(ip, StrPort, Request);
}
打开 request.txt,一目了然
POST /AVTransport/action HTTP/1.1
Cache-Control: no-cache
Connection: Close
Pragma: no-cache
Host: 192.168.2.104:1068
User-Agent: Microsoft-Windows/6.3 UPnP/1.0 Microsoft-DLNA DLNADOC/1.50
FriendlyName.DLNA.ORG: sonichy-PC
Content-Length: 916
Content-Type: text/xml; charset="utf-8"
SOAPAction: "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI"
0
https://vod3.bdzybf3.com/20210523/Z14ku6y7/index.m3u8
-
Capital Edinburgh 373
object.item.audioItem.audioBroadcast
SA_RINCON65031_
SOAPAction 请求头
SOAP 的 XML
我改成了QNetworkRequest,注意 url 的协议要写,ContentType 要写。
QString DLNAClient::UploadFileToPlay(QString ControlURL, QString UrlToPlay)
{
QString XML = "\n"
"\n"
"\n"
"\n"
"0 \n";
XML += "" + UrlToPlay.replace(" ", "%20") + " \n";
XML += " \n";//" + Desc() + "
XML += " \n";
XML += " \n"
" \n";
QString surl = scheme + IP + ":" + port + "/" + ControlURL;
qDebug() << surl;
return postReply(surl, XML);
}
QByteArray DLNAClient::postReply(QString surl, QString spost)
{
QNetworkAccessManager *NAM = new QNetworkAccessManager;
QNetworkRequest request;
request.setUrl(QUrl(surl));
request.setHeader(QNetworkRequest::ContentTypeHeader, "text/xml; charset=\"utf-8\"");
request.setRawHeader("SOAPAction", "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI");
QByteArray BA_post;
BA_post.append(spost.toUtf8());
QNetworkReply *reply = NAM->post(request, BA_post);
QEventLoop loop;
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
loop.exec();
reply->deleteLater();
return reply->readAll();
}
返回这个就成功了:
如何接收投屏还没头绪。
源码:sonichy/HTYDLNA