Hi Mark,
I understand the first part of your answer but the end seems wrong to me :
I agree. This is tricky stuff and the issue is complicated by the
fact that the MPRIS2 API we use doesn't match perfectly onto DLNA DMRs.
I could
not agree more.
Here is my recommendation.
When we discover a new DMR we should check to see what version of
DLNA, if any, the renderer supports. We can discover this information
by checking for the presence of the <dlna:X_DLNADOC> tag.
If the renderer does not support DLNA, I suggest we ignore
X_DLNA_SeekTime completely. Our CanSeek property will be true if Seek
is present in the CurrentTransportActions.
If the renderer supports DLNA 1.5 or greater, CanSeek is true for the
current track if and only if CurrentTransportActions contains both
X_DLNA_SeekTime and Seek.
A new property CanByteSeek will be true if and only if the
CurrentTransportActions contains both Seek and X_DLNA_SeekByte. There
is no need to check the DLNA version number here.
Ok for all of that.
There is a slight discrepancy between DLNA and MPRIS2 here. The
MRPIS2 CanSeek property means that both Absolute and Relative seeking
are supported, e.g., both Seek and SetPosition will work with the
current file. However, the presence of Seek and X_DLNA_SeekTime in
the CurrentTransportActions imply only that Seek will work. They
provide no information about SetPosition.
My feeling is that providing this does not affect certification this
is okay as fixing this properly would be quite a lot of work and would
be confusing for clients as they would need to use an extended API to
determine whether they could seek or not. We would need two new
properties, CanSeekRel, CanSeekAbs.
From what I understand from the UPnP-AV spec, the semantic of Seek in
UPnP is equivalent to SetPosition in mpris:
[AVTransport:2 Service Template Version 1.01] « Seek(InstanceID,
“REL_TIME”, “00:00:10”) will move the current position to 10 seconds
from the beginning of the track and the RelativeTimePosition state
variable will contain the value “00:00:10” after the Seek() action is
completed. »
So, to do an mpris-like seek in UPnP, we should do something like this :
⋅ Seek(InstanceID, “REL_TIME”, “RelativeTimePosition + 00:00:10”)
The Unit ”ABS_TIME” meens from the beginning of the media, so if we are
playing a CD, where each track is 5mn long:
⋅ Seek(InstanceID, “ABS_TIME”, “00:15:10”)
Will set “RelativeTimePosition” to 10" in the fourth track, wherever we
are in the media.
So, I really don't think we need these variables “CanSeekRel” and
“CanSeekAbs”, except if we plan to seek in whole media, do we ?
CanSeek would be true if DLNA is not supported and REL_TIME and
ABS_TIME are included in the A_ARG_TYPE_SeekMode state variable. If
DLNA 1.5 is supported CanSeek would be set to False.
CanSeekRel would be set to true if DLNA is not supported and REL_TIME
is included in the A_ARG_TYPE_SeekMode state variable or DLNA is
supported and both seek and X_DLNA_SeekTime are present in the
CurrentTransportActions.
CanSeekAbs would be set to true if DLNA is not supported and ABS_TIME
is included in the A_ARG_TYPE_SeekMode state variable. Otherwise it
would be set to false.
So, it seems to me to be easier just to set CanSeek to true even if we
cannot be sure whether a call to SetPosition will work. If the client
calls SetPosition when it is not supported he will receive an error.
If on the other hand this causes problems with certification we will
have to introduce these new variables.
Regards,
Mark
Tell me what you think about all of this.
Séb