thibauts/node-upnp-mediarenderer-client

Support for subtitles through UPnP DIDL-Lite

thibauts opened this issue · 43 comments

Support for subtitles through UPnP DIDL-Lite

Hi @xat, I'm trying to get DIDL-Lite subtitles working but I'm starting to doubt my TV supports external subtitles at all. I see you playing with DLNA so I was thinking you may help me test a few things :p

What TV brand model do you have ?

xat commented

I've got a Samsung UE55H6470. Sure, what do I have todo to test? :D

Hm, Samsungs support external subtitles through DLNA headers when serving content, "sadly" .. Example here in case you're interested https://gist.github.com/thibauts/5f5f8d8ce6566c8289e6

xat commented

Hmm, didn't work. Must the VTT be on the same host as the media file?
I tried an VTT on a different host res.setHeader('CaptionInfo.sec', 'http://companiait.com.ar/1.vtt')

I don't think so. But you should try with an SRT file. I'm not sure many TVs support VTTs.

xat commented

No luck with http://www.n01a.org/tesla.srt either :(

That's strange .. I had it work on a friend's samsung. Have you tried playing the media file from the same server ?

xat commented

I'll try

xat commented

Same problem when the subtitles are on the same host. However, I see that there is a request from the TV to the subtitles route.

Do you serve the proper content type ?

xat commented

I didn't. But also with the correct content type no luck. Maybe I'm also missing some TV setting. Bought it a week ago and didn't try subtitles at all yet on it.

I'm currently implementing DIDL-Lite metadata and trying to cover all subtleties even though I won't be able to the the result with my Bravia. Maybe it'll help with your case, we'll see. I should be done in a few hours.

xat commented

okay, cool!

Done

xat commented

nice, but I get a warning now on my TV saying "the selected file is currently not supported"

If you don't provide metadata there shouldn't be any difference. Can you show me your load call ?

xat commented

The warning appeared with the meta-data

    cli.load(url + '/media', { autoplay: true, contentType: type, metadata: {
      title: 'Some Movie Title',
      creator: 'John Doe',
      type: 'video', // can be 'video', 'audio' or 'image'
      subtitlesUrl: url + '/media.srt'
    } }, function() { ... }

Internally metadata is serialized to DIDL-Lite here and only present options are added. Can you try to provide, first an empty map {} then gradually add the various options to see where it breaks ?

xat commented

yes, without the 'subtitlesUrl' field it works.

This is how my media.srt route looks like:

      route.get('/media.srt', function (req, res) {
        res.setHeader('Content-type', 'text/srt')
        res.setHeader('Access-Control-Allow-Origin', '*')
        return fs.createReadStream(opts.subtitles).pipe(res)
      })
xat commented

If I open the media.srt route within the browser the subtitles-file shows up

I have no obvious clue. Maybe the SRT format is not supported by your TV. Or maybe one of the ways the subtitles are advertised in buildMetadata makes your TV choke. Try to comment the various SubElements and see how it goes.

Or maybe your TV supports external SRT subtitles but not through DIDL-Lite ...

This is the difficult part with DLNA, without access to various brands it's really difficult to debug

xat commented

The error dosn't appear when I comment out:

    var res = et.SubElement(item, 'res');
    res.set('protocolInfo', 'http-get:*:text/srt:*');
    res.text = metadata.subtitlesUrl;
xat commented

should srt appear in the list returned by getSupportedProtocols() ?

Ok that's what I suspected too. Yes, when using this tag, having the same protocolInfo appearing in the supported protocols would seem consistent. I don't have it yet my TV doesn't blink an eye.

I'm not even sure this tag is of much use so it may be best to remove it, or at least comment it out for now.

I commented it and published an update to NPM.

xat commented

Thanks, I'll checkout the Samsung manual if I'm missing something else or just live with it :)

@thibauts is the http-get:*:text/srt:* tag needed to support srt subtitles?

My Samsung don't pick up subtitles without res.set('protocolInfo', 'http-get:*:text/srt:*');
But if I uncomment lines it says "The selected file is not currently supported" :)

I don't understand. So it never works ?

Yes.

  1. If lines are commented: I don't see any request from TV to pickup subtitles.
  2. If lines are uncommented: I see couple of requests (HEAD and GET) and then TV show "The selected file is not currently supported". This may be my code, because I'm not sure which headers TV expects to find when ask about subtitles. I try to serve them (subs) via web server which failed too.

Yes, headers may be important ... Have you tried to play exactly the same file with the same subtitles with other upnp software ? It it works, sniffing the traffic would settle it :)

The subs are OK. They are showing with minidlna. Yep I will dump some traffic at some point :)

That would be awesome :)

Yeh ... I was just missing CaptionInfo.sec header.

So lines must stay commented. If they are uncommented Samsung will pick only subs file and will display "The selected file is not currently supported" which is correct in some way.

If you put CaptionInfo.sec Samsung will start to play movie and then will fetch subs. It works this way on web server too (lighttpd w/o any mime config).

@drJeckyll can you give a bit more info on how to set CaptionInfo.sec properly?

There is no magic:
response.setHeader('CaptionInfo.sec', 'http://192.168.1.1:8888/blahblah.srt')
You must put this header in place where you serve video file, so Samsung can pick it up when start to play video. Whole thing is a real mess :)

what will happen if protocolInfo and sec:captionInfo headers are still passed?

If you have in mind protocolInfo with srt from upnp-mediarenderer-client then you are lost just like me :)

Don't set res.set('protocolInfo', 'http-get:*:text/srt:*');. Or just for new versions of Samsung (C,D,E,F - minidlna code says and I can say H from my TV) don't use it. For any other TV's may be right to use it, I don't know.

But my confusion (and may be yours too) come from fact that I assume that Samsung will pick subs from client headers. Which is wrong. Samsung pick subs from server headers ie you must put CaptionInfo.sec in server response header, not in client request header.

Now to your question. If you put protocolInfo in client request header, then Samsung C,D,E,F, H will show "The selected file is not currently supported", because TV will pick just subs file and never will ask for movie file.

Check this: https://github.com/drJeckyll/dlnapush/blob/master/dlnapush.js

That's weird as hell. :)

We should look into how apps that support most TVs do it - e.g. Popcorn Time?

I cannot find anything different than what we're doing here, and looking at the butter source, there's no setting of headers anywhere. :(

Check minidlna source. I found my mistake from their code.

AFAIK popcorn time used this very module for DLNA so they aren't doing any better.

As @drJeckyll said minidlna is a great resource. This software and others have worked out a crazy amount of edge cases through feedback, I guess. That said, our support for straight video isn't bad and probably won't get much better. What's more hairy is subtitles, their formats and ways of being delivered. And that's probably because there's no standard for external (non embedded) subtitles in DLNA.

Following this issue I just pushed an update that should help people that need the res tag in the DIDL-Lite metadata. Let me know if it solves it for you.

LG pre-webos: fine with and without subs