Closed attah closed 8 months ago
It is so nice to hear that someone finds it useful :smile:. If you have any special needs regarding API just let me know.
Yes, HLS (or DASH) is not supported.. but I can look into it and check what could be done. Could you please provide me (as an example) a URL to some content? It could be something from svtplay.se.
BTW, Maybe you have already noticed it but also Kodimote exposes DBus API. For instance Quickddit uses it to share Youtube links.
I had actually missed that aspect of kodimote, and that it wasn't openrepos-only. I'll check on it too. Any chances of seeing you on #sailfishos on freenode? Here is a link, but probably due to expire in a week since it's a weather report: http://svtplay2r-f.akamaihd.net/i/world/open/20190114/1392573-009A/PG-1392573-009A-VADER_,988,240,348,456,636,1680,2796,.mp4.csmil/master.m3u8 You can drop number values from the comma separated list to reduce the number of bitrates available, but keep a first and last comma.
Also, I'm not asking for HLS termination in the app itself, just relaying the URL to the renderer... (HLS actually already works in the QML MediaPlayer, so more local playback isn't really needed)
Here is what i did to hackishly play stuff on my renderer (URL made to be variable, $1, not what i ran with though):
#!/bin/bash curl -H 'Content-Type: text/xml; charset=utf-8' -H 'SOAPAction: "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI"' -d '<?xml version="1.0" encoding="utf-8"?><s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><u:SetAVTransportURI xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><CurrentURI>$1</CurrentURI><CurrentURIMetaData></CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>' 'http://192.168.1.249:60099/AVTransport/control'
#!/bin/bash curl -H 'Content-Type: text/xml; charset=utf-8' -H 'SOAPAction: "urn:schemas-upnp-org:service:AVTransport:1#Play"' -d '<?xml version="1.0" encoding="utf-8"?><s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><u:Play xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><Speed>1</Speed></u:Play></s:Body></s:Envelope>' 'http://192.168.1.249:60099/AVTransport/control'
Method from here: http://www.accella.net/knowledgebase/sending-a-video-content-to-a-dlnaupnp-softwaredevice-using-curl/
Actually, Jupii does more than just passing URL. To provide as wide as possible compatibility with different renderers I've decided to proxy every HTTP stream. It enables me to implement additional features like removing in-stream meta data that "confuses" some devices. In current implementation when you add m3u URL Jupii tries to discover direct stream (direct URL to media resource) and than it downloads small portion of the data to find out what a media type and meta data of the stream is. Unfortunately this mechanism doesn't work well with HLS playlist...
Anyway, I will fix it by adding detection if m3u playlist is a HLS playlist instead regular one. Thanks to URL you provided I've already tested it and the fix seems to work fine with Kodi. I'm not sure how this test is representative because from my experience Kodi is extremely liberal in terms of accepting different variants of protocols, codecs and URLs. It literally can play anything!
The fix will be included in the next beta release (possibly in 2-3 days).
I realize that, and it is a very valuable feature, one that i could certainly not find the time to replicate. However, in this particular case it would be a good feature and perhaps sensible default option (not Jupii-global, but rather my use of it) to not proxy the stream and thereby drain the battery. Regardless of the outcome, thanks for your attention and dedication :)
BTW... there are really cheap ~$12 DLNA renderers on eBay etc "Mirascreen", i got a "V2" for testing this, since my TV is the wrong class of device. I will at least test with that.
In 7e35a99a5951c3f196aa458c9ed6accbe684edba I've added fix to detect HLS playlist and apply proxy-less handling. It is just "workaround" rather than final solution. As you suggested, I have to re-think this "proxy everything" concept and introduce less radical approach.
I would be grateful if you could test Jupii recent 2.2.0 release (it is available via OpenRepos).
Thanks for that! Proxying everything in the spirit of compatibility is a fair first version, nothing wrong with that... but optimizations/improvements are nice :)
I need to fix my reading comprehension... I built my own from source, but that should be equivalent i guess. Seems to work fine for just inputting the uri, both with proxying and without. Haven't done the dbus integration on my side, but i should get going with that now. One thing though, are there no controls apart from volume?
One thing with running in proxy mode is that the automatic bitrate selection was using a quite low setting, delegating it worked better (for me, this time). I'm already planning to limit the bitrate choices on my end with the stupid and specific method i described previously. A generic implementation suitable for Jupii might be harder.
Btw, may i steal your icon-m-device.png for using as an icon for invoking Jupii from my app?
Didn't have time to start hacking until now in the evening, but POC is coming along nicely (i.e. i can add streams to Jupii from my app). I guess i had sort of expected addUrl to do more of playUrl, but keeping the "old" streams there has its use... Probably mainly need to figure out how to switch to jupii, if at all possible.
I threw in a "MimeType=x-scheme-handler/jupii;" to the harbour-jupii.desktop file. xdg-open jupii:// does launch the app, but a new instance of it, but Qt.openUrlExternally("jupii://") in my app does nothing. Oh, and adding the same url again does just that... it will appear multiple times in the list in the list. Any interface where i could avoid this would be much appreciated.
Very briefly, everything is doable. For instance I can add new methods to DBus API like: addUrlOnce and addUrlOnceAndPlay... Right now I'm not available for few days but when get back I will go through all your questions/ideas.
Hello.. I'm back
One thing though, are there no controls apart from volume?
Definitely they are. Just tap on bottom panel. It will expand and other controls will be visible. Like on this screenshot.
may i steal your icon-m-device.png
Sure, no problem. I will be delighted. Raw SVG files are here.
i had sort of expected addUrl to do more of playUrl, but keeping the "old" streams there has its use Oh, and adding the same url again does just that... it will appear multiple times in the list in the list
You right it is useless in the current form. In df61f3030c9731966c406e434c2d0759d7331e0e I've added new methods: addUrlOnce and addUrlOnceAndPlay. Description and API details are in org.jupii.xml. Hopefully It will address all your use cases. If not just let me know.
Thanks, awesome work! I had completely missed the bottom panel... but now when i know what to look for i can see it appearing and then quickly disappearing when starting to play something. I've compiled a new version, which didn't change anything in that regard. Digging in to the logs to see if i can understand what went wrong.
It happens during this log snippet anyway: https://pastebin.com/Wk7MdXe7
BTW... Jupii hangs for me if i power off the DLNA renderer. Should i open a separate issue?
Another thought and possible feature request related to this... it would be neat if one could raise/front/activate/... Jupii from the invoking app, either explicitly or as part of addUrlOnceAndPlay.
Currently i do Qt.openUrlExternally(Qt.resolvedUrl("/usr/share/applications/harbour-jupii.desktop")) which works well enough... it just feels wrong...
One example of what i was thinking is perhaps: https://github.com/sailfishos/sailfish-office/blob/fdf5a30468f0b79ac975f2215abf3e51b435e3df/dbusadaptor.cpp#L42
I had completely missed the bottom panel... but now when i know what to look for i can see it appearing and then quickly disappearing when starting to play something.
[D] AVTransport::updateCurrentTransportActions:1384 - CurrentTransportActions:
[D] AVTransport::updateCurrentTransportActions:1385 - actions: 4
[D] AVTransport::updateCurrentTransportActions:1386 - Next: 0
[D] AVTransport::updateCurrentTransportActions:1387 - Pause: 0
[D] AVTransport::updateCurrentTransportActions:1388 - Play: 4
[D] AVTransport::updateCurrentTransportActions:1389 - Previous: 0
[D] AVTransport::updateCurrentTransportActions:1390 - Seek: 0
[D] AVTransport::updateCurrentTransportActions:1391 - Stop: 0
It is weird but your device reports that only Play
action is supported. The control panel is visible only when you can use it. When content is playing, you cannot do anything so, the panel gets hidden.
I've notice that you enabled "Redirection mode". Please try to use "Proxy" instead. In Proxy mode Jupii adds extra HTTP header contentFeatures.dlna.org
which contains "magic" flags that tell DLNA renderer what are the stream capabilities. I've added extra hook for HLS so in Proxy mode, Jupii will relay only playlist file but the actual video stream will go directly. Maybe lack of DLNA flags is the problem.
Additionally, could you please check if you can play video/audio files stored on your phone and control panel is visible?
Jupii hangs for me if i power off the DLNA renderer.
Yes. I'm aware of that. I'm going to fix it but is has low priority right now.
Yes, quite weird... Volume does work, and that's a pretty worthless feature compared to play/pause. Is that reported/handled separately? It's not every time that the controls flash past, sometimes they just never appear. I've tried with proxy mode and local video, no difference. Logs for playback of local file: https://pastebin.com/6rDVkr4X
I can confirm that it can at least pause, reporting could still be haywire of course. I took my curl example above replaced Play with Pause throughout. Didn't even have to take out the speed entry. Tested with both a file that was local to the phone, and a redirected stream.
Volume does work, and that's a pretty worthless feature compared to play/pause. Is that reported/handled separately?
Yes. Volume control is a part of completely different UPnP service (RenderingControl) and they are handled separately. Support for Play/Pause/Stop/Seek can be retrieved with GetCurrentTransportActions
action (for reference check chapter 2.4 of AVTransport spec). It appears that your device sends back that only Play
is supported. You already confirmed that Pause
works as expected, so possibly it is just a crappy UPnP implementation.
In 3b49b7489cf3e731b5d24a02693439c39b2bb455 I've added workaround to ignore GetCurrentTransportActions
result. Could you please test it? It is new branch (ignore-actions-supported), so you need to checkout to it first.
That made controls work. :) This is that output after pausing:
[D] AVTransport::updateCurrentTransportActions:1394 - CurrentTransportActions:
[D] AVTransport::updateCurrentTransportActions:1395 - actions: 2
[D] AVTransport::updateCurrentTransportActions:1396 - Next: 0
[D] AVTransport::updateCurrentTransportActions:1397 - Pause: 2
[D] AVTransport::updateCurrentTransportActions:1398 - Play: 0
[D] AVTransport::updateCurrentTransportActions:1399 - Previous: 0
[D] AVTransport::updateCurrentTransportActions:1400 - Seek: 0
[D] AVTransport::updateCurrentTransportActions:1401 - Stop: 0
I'll see if I can't poke around the querying a bit.
Output of GetCurrentTransportActions Paused:
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:GetCurrentTransportActionsResponse xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
<Actions>Pause</Actions>
</u:GetCurrentTransportActionsResponse>
</s:Body>
Playing:
<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<u:GetCurrentTransportActionsResponse xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
<Actions>Play</Actions>
</u:GetCurrentTransportActionsResponse>
</s:Body>
</s:Envelope>
And did I mention seeking works? smh
It is very very weird.. but it's funny as well. It seems that GetCurrentTransportActions
returns current transport state instead available actions. When state is Paused
device returns that only Pause
action is available, when state is Playing
it returns Play
action. It should be completely opposite.
The only solution I see right now is to add extra switch (in the Settings) to assume that all control actions are always supported.
Yes indeed. I suspect there may be a language barrier between the spec and the implementers. That is a very good solution, thanks. :) Perhaps something to indicate to the user that the Renderer reported no supported actions too, instead of controls being completely missing. Interestingly enough, they responded to a support request. Sure it's still the normal first line crap, but maybe, just maybe they can even fix it.
Just to sum up. Extra configuration option (switch in the Settings) could be too much confusing so I've resolved it differently. From 8f87a27cbcaabf71a0b01410c6dc2ea7adc34d29 supported actions retrieved with GetCurrentTransportActions
will be ignored if they are meaningless like in the examples above.
Any chance of a release in Harbour? I'm to a level where I'm considering to release the svt play app, not that I'm in a hurry, or that Jupii integration is completely essential. Anyway, here is my attempt at an abstraction for integration https://github.com/attah/harbour-s2play/blob/master/qml/pages/JupiiConnection.qml
Yes, Jupii is now ready for the release. Actually, it awaits to be approved by Harbour reviewer.
Anyway, here is my attempt at an abstraction for integration
Looks awesome. Additionally you could also use canControl
property. When it is true
it means that Jupii is connected to DLNA device and it makes sense to use AddX methods. Here is my super simple QML app that I'm using to test DBus. The canControlPropertyChanged
function is called whenever canControl
property get changed. For instance, in your app, "send to Jupii" button could be visible only when canControl
is true.. I've copied this concept from Quickddit and Kodimote DBus integration.
Great news :) For a while there the signal handler wasn't working for me, but it is and it seems i can simplify down to where the whole component is just the DBusInterface, no visibility hook needed. Thanks. I'll let it stew and see if i lost any robustness.
Meh, it's not reliable for me... so doing a compromise
Just an info => Jupii 2.2.2 release is now available in Harbour
Any chance you could add bringing Jupii to front/focus when the addUrlOnceAndPlay method is invoked? Seems Jolla broke my way of "doing it for you" (suggestion for what to do in link) https://together.jolla.com/question/201843/3028-xdg-open-desktop-dont-open-application-anymore/?comment=202115#comment-202115
Done in a7d9b15479b539d3e57df4503c2d4a41a5d6bbe5.
Thanks, works great!
It is not HLS already supported?
It is not HLS already supported?
I would not say that HLS is 100% supported. There is a workaround.
When URL points to HLS playlist (special kind of M3U playlist) Jupii pass this playlist without any change to UPnP device. It might work for some devices (Kodi for instance) but for most it will not work because devices don't understand HLS.
The ideal implementation would be to convert on-the-fly HLS to "normal" single bit-rate stream and then pass this stream to UPnP device. It is possible but hard to implement.
I know that you can implement HLS 100%. ; )
Closing this old issue report. HLS (but only for audio) is supported from version 2.14.
What an amazing idea with a Dbus API! This basically solves the issue of all other developers having to do their own DLNA integration. (I arrived here from working on a a svtplay.se app for SFOS) However, I can't seem to add a HLS (http://x.y/z.m3u8) stream as an URL. Could you please look in to if that can be made possible?
I have separately verified that the renderer can play it when given the same url i tested with.