Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't connect to AVTransport #43

Closed
Mikescops opened this issue Jun 6, 2022 · 34 comments
Closed

Can't connect to AVTransport #43

Mikescops opened this issue Jun 6, 2022 · 34 comments

Comments

@Mikescops
Copy link
Contributor

Hello,

Thanks for building this tool.
I can't connect to my DLNA speakers as I am getting the following error:

SendtoTV set AVT Transport error: setAVTransportSoapCall Do POST error: Post "http://192.168.1.32:54380/upnp/control/AVTransport": POST http://192.168.1.32:54380/upnp/control/AVTransport giving up after 4 attempt(s)

I'm running the tool on Ubuntu 20, and the speakers are working well with other DLNA renderer (like the default one in Windows).

Let me know if you need more information.

@alexballas
Copy link
Owner

alexballas commented Jun 6, 2022

Hello @Mikescops,

I know that error is not super useful. It means that one of the DLNA calls to your device returned a bad HTTP error code. That could be related to bad file format, bad handling of a specific file name. I can provide a version of Go2TV that provides some debug level logs to get to the bottom of the issue but first it would be good to share some info on your setup.

  • Did you use the CLI or the GUI mode?
  • What file did you try to cast?
  • What Speakers do you have? (brand)
  • Is the error intermittent or you always get it?
  • Did you try any other audio files?

@Mikescops
Copy link
Contributor Author

Did you use the CLI or the GUI mode?

I tried with both 👍

What file did you try to cast?

I tried to cast a FLAC audio file (I also tried the transcode option too without success, tho' it seems to be for video)

What Speakers do you have?

I have a SONY HT-A9, which is a pretty recent device.

Is the error intermittent or you always get it?

The error is consistent over time.

Did you try any other audio files?

Yes i tried with MP3 too, and also tried on a Windows computer.


All in all, this doesn't seems to be dependant on the codecs as the receiver is able to receive such formats (bitrates too). The error is consistent over time and platform.


If that helps, here is the UPNP xml file:

Click to expand
<root>
    <specVersion>
        <major>1</major>
        <minor>0</minor>
    </specVersion>
    <device>
        <deviceType>urn:schemas-upnp-org:device:MediaRenderer:1</deviceType>
        <friendlyName>HT-A9</friendlyName>
        <manufacturer>Sony Corporation</manufacturer>
        <manufacturerURL>http://www.sony.net/</manufacturerURL>
        <modelName>HT-A9</modelName>
        <modelNumber>BAR-2021</modelNumber>
        <UDN>uuid:00000000-0000-1010-8000-f84e17521a0b</UDN>
        <dlna:X_DLNACAP>playcontainer-0-1</dlna:X_DLNACAP>
        <dlna:X_DLNADOC>DMR-1.50</dlna:X_DLNADOC>
        <av:X_StandardDMR>1.1</av:X_StandardDMR>
        <iconList>
            <icon>
                <mimetype>image/png</mimetype>
                <width>120</width>
                <height>120</height>
                <depth>24</depth>
                <url>/a9_device_icon_120.png</url>
            </icon>
            <icon>
                <mimetype>image/jpeg</mimetype>
                <width>120</width>
                <height>120</height>
                <depth>24</depth>
                <url>/a9_device_icon_120.jpg</url>
            </icon>
            <icon>
                <mimetype>image/png</mimetype>
                <width>48</width>
                <height>48</height>
                <depth>24</depth>
                <url>/a9_device_icon_48.png</url>
            </icon>
            <icon>
                <mimetype>image/jpeg</mimetype>
                <width>48</width>
                <height>48</height>
                <depth>24</depth>
                <url>/a9_device_icon_48.jpg</url>
            </icon>
        </iconList>
        <serviceList>
            <service>
                <serviceType>urn:schemas-upnp-org:service:RenderingControl:1</serviceType>
                <serviceId>urn:upnp-org:serviceId:RenderingControl</serviceId>
                <SCPDURL>/RenderingControlSCPD.xml</SCPDURL>
                <controlURL>/upnp/control/RenderingControl</controlURL>
                <eventSubURL>/upnp/event/RenderingControl</eventSubURL>
            </service>
            <service>
                <serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType>
                <serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId>
                <SCPDURL>/ConnectionManagerSCPD.xml</SCPDURL>
                <controlURL>/upnp/control/ConnectionManager</controlURL>
                <eventSubURL>/upnp/event/ConnectionManager</eventSubURL>
            </service>
            <service>
                <serviceType>urn:schemas-upnp-org:service:AVTransport:1</serviceType>
                <serviceId>urn:upnp-org:serviceId:AVTransport</serviceId>
                <SCPDURL>/AVTransportSCPD.xml</SCPDURL>
                <controlURL>/upnp/control/AVTransport</controlURL>
                <eventSubURL>/upnp/event/AVTransport</eventSubURL>
            </service>
            <service>
                <serviceType>urn:schemas-sony-com:service:ScalarWebAPI:1</serviceType>
                <serviceId>urn:schemas-sony-com:serviceId:ScalarWebAPI</serviceId>
                <SCPDURL>/ScalarWebApiSCPD.xml</SCPDURL>
                <controlURL>/ScalarAPI</controlURL>
                <eventSubURL />
            </service>
        </serviceList>
        <av:X_ScalarWebAPI_DeviceInfo>
            <av:X_ScalarWebAPI_Version>1.0</av:X_ScalarWebAPI_Version>
            <av:X_ScalarWebAPI_BaseURL>http://192.168.1.32:10000/sony</av:X_ScalarWebAPI_BaseURL>
            <av:X_ScalarWebAPI_ServiceList>
                <av:X_ScalarWebAPI_ServiceType>guide</av:X_ScalarWebAPI_ServiceType>
                <av:X_ScalarWebAPI_ServiceType>audio</av:X_ScalarWebAPI_ServiceType>
                <av:X_ScalarWebAPI_ServiceType>avContent</av:X_ScalarWebAPI_ServiceType>
                <av:X_ScalarWebAPI_ServiceType>system</av:X_ScalarWebAPI_ServiceType>
                <av:X_ScalarWebAPI_ServiceType>appControl</av:X_ScalarWebAPI_ServiceType>
            </av:X_ScalarWebAPI_ServiceList>
        </av:X_ScalarWebAPI_DeviceInfo>
        <av:X_CIS_DeviceInfo>
            <av:X_CIS_Version>1,2</av:X_CIS_Version>
            <av:X_CIS_v1Info>
                <av:X_CIS_Port>33335</av:X_CIS_Port>
            </av:X_CIS_v1Info>
            <av:X_CIS_v2Info>
                <av:X_CIS_Port>33336</av:X_CIS_Port>
            </av:X_CIS_v2Info>
        </av:X_CIS_DeviceInfo>
    </device>
</root>

And the AVTransportSCPD.xml :

Click to expand
<scpd>
    <specVersion>
        <major>1</major>
        <minor>0</minor>
    </specVersion>
    <actionList>
        <action>
            <name>SetAVTransportURI</name>
            <argumentList>
                <argument>
                    <name>InstanceID</name>
                    <direction>in</direction>
                    <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                </argument>
                <argument>
                    <name>CurrentURI</name>
                    <direction>in</direction>
                    <relatedStateVariable>AVTransportURI</relatedStateVariable>
                </argument>
                <argument>
                    <name>CurrentURIMetaData</name>
                    <direction>in</direction>
                    <relatedStateVariable>AVTransportURIMetaData</relatedStateVariable>
                </argument>
            </argumentList>
        </action>
        <action>
            <name>SetNextAVTransportURI</name>
            <argumentList>
                <argument>
                    <name>InstanceID</name>
                    <direction>in</direction>
                    <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                </argument>
                <argument>
                    <name>NextURI</name>
                    <direction>in</direction>
                    <relatedStateVariable>NextAVTransportURI</relatedStateVariable>
                </argument>
                <argument>
                    <name>NextURIMetaData</name>
                    <direction>in</direction>
                    <relatedStateVariable>NextAVTransportURIMetaData</relatedStateVariable>
                </argument>
            </argumentList>
        </action>
        <action>
            <name>GetMediaInfo</name>
            <argumentList>
                <argument>
                    <name>InstanceID</name>
                    <direction>in</direction>
                    <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                </argument>
                <argument>
                    <name>NrTracks</name>
                    <direction>out</direction>
                    <relatedStateVariable>NumberOfTracks</relatedStateVariable>
                </argument>
                <argument>
                    <name>MediaDuration</name>
                    <direction>out</direction>
                    <relatedStateVariable>CurrentMediaDuration</relatedStateVariable>
                </argument>
                <argument>
                    <name>CurrentURI</name>
                    <direction>out</direction>
                    <relatedStateVariable>AVTransportURI</relatedStateVariable>
                </argument>
                <argument>
                    <name>CurrentURIMetaData</name>
                    <direction>out</direction>
                    <relatedStateVariable>AVTransportURIMetaData</relatedStateVariable>
                </argument>
                <argument>
                    <name>NextURI</name>
                    <direction>out</direction>
                    <relatedStateVariable>NextAVTransportURI</relatedStateVariable>
                </argument>
                <argument>
                    <name>NextURIMetaData</name>
                    <direction>out</direction>
                    <relatedStateVariable>NextAVTransportURIMetaData</relatedStateVariable>
                </argument>
                <argument>
                    <name>PlayMedium</name>
                    <direction>out</direction>
                    <relatedStateVariable>PlaybackStorageMedium</relatedStateVariable>
                </argument>
                <argument>
                    <name>RecordMedium</name>
                    <direction>out</direction>
                    <relatedStateVariable>RecordStorageMedium</relatedStateVariable>
                </argument>
                <argument>
                    <name>WriteStatus</name>
                    <direction>out</direction>
                    <relatedStateVariable>RecordMediumWriteStatus</relatedStateVariable>
                </argument>
            </argumentList>
        </action>
        <action>
            <name>GetTransportInfo</name>
            <argumentList>
                <argument>
                    <name>InstanceID</name>
                    <direction>in</direction>
                    <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                </argument>
                <argument>
                    <name>CurrentTransportState</name>
                    <direction>out</direction>
                    <relatedStateVariable>TransportState</relatedStateVariable>
                </argument>
                <argument>
                    <name>CurrentTransportStatus</name>
                    <direction>out</direction>
                    <relatedStateVariable>TransportStatus</relatedStateVariable>
                </argument>
                <argument>
                    <name>CurrentSpeed</name>
                    <direction>out</direction>
                    <relatedStateVariable>TransportPlaySpeed</relatedStateVariable>
                </argument>
            </argumentList>
        </action>
        <action>
            <name>GetPositionInfo</name>
            <argumentList>
                <argument>
                    <name>InstanceID</name>
                    <direction>in</direction>
                    <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                </argument>
                <argument>
                    <name>Track</name>
                    <direction>out</direction>
                    <relatedStateVariable>CurrentTrack</relatedStateVariable>
                </argument>
                <argument>
                    <name>TrackDuration</name>
                    <direction>out</direction>
                    <relatedStateVariable>CurrentTrackDuration</relatedStateVariable>
                </argument>
                <argument>
                    <name>TrackMetaData</name>
                    <direction>out</direction>
                    <relatedStateVariable>CurrentTrackMetaData</relatedStateVariable>
                </argument>
                <argument>
                    <name>TrackURI</name>
                    <direction>out</direction>
                    <relatedStateVariable>CurrentTrackURI</relatedStateVariable>
                </argument>
                <argument>
                    <name>RelTime</name>
                    <direction>out</direction>
                    <relatedStateVariable>RelativeTimePosition</relatedStateVariable>
                </argument>
                <argument>
                    <name>AbsTime</name>
                    <direction>out</direction>
                    <relatedStateVariable>AbsoluteTimePosition</relatedStateVariable>
                </argument>
                <argument>
                    <name>RelCount</name>
                    <direction>out</direction>
                    <relatedStateVariable>RelativeCounterPosition</relatedStateVariable>
                </argument>
                <argument>
                    <name>AbsCount</name>
                    <direction>out</direction>
                    <relatedStateVariable>AbsoluteCounterPosition</relatedStateVariable>
                </argument>
            </argumentList>
        </action>
        <action>
            <name>GetDeviceCapabilities</name>
            <argumentList>
                <argument>
                    <name>InstanceID</name>
                    <direction>in</direction>
                    <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                </argument>
                <argument>
                    <name>PlayMedia</name>
                    <direction>out</direction>
                    <relatedStateVariable>PossiblePlaybackStorageMedia</relatedStateVariable>
                </argument>
                <argument>
                    <name>RecMedia</name>
                    <direction>out</direction>
                    <relatedStateVariable>PossibleRecordStorageMedia</relatedStateVariable>
                </argument>
                <argument>
                    <name>RecQualityModes</name>
                    <direction>out</direction>
                    <relatedStateVariable>PossibleRecordQualityModes</relatedStateVariable>
                </argument>
            </argumentList>
        </action>
        <action>
            <name>GetTransportSettings</name>
            <argumentList>
                <argument>
                    <name>InstanceID</name>
                    <direction>in</direction>
                    <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                </argument>
                <argument>
                    <name>PlayMode</name>
                    <direction>out</direction>
                    <relatedStateVariable>CurrentPlayMode</relatedStateVariable>
                </argument>
                <argument>
                    <name>RecQualityMode</name>
                    <direction>out</direction>
                    <relatedStateVariable>CurrentRecordQualityMode</relatedStateVariable>
                </argument>
            </argumentList>
        </action>
        <action>
            <name>Stop</name>
            <argumentList>
                <argument>
                    <name>InstanceID</name>
                    <direction>in</direction>
                    <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                </argument>
            </argumentList>
        </action>
        <action>
            <name>Play</name>
            <argumentList>
                <argument>
                    <name>InstanceID</name>
                    <direction>in</direction>
                    <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                </argument>
                <argument>
                    <name>Speed</name>
                    <direction>in</direction>
                    <relatedStateVariable>TransportPlaySpeed</relatedStateVariable>
                </argument>
            </argumentList>
        </action>
        <action>
            <name>Pause</name>
            <argumentList>
                <argument>
                    <name>InstanceID</name>
                    <direction>in</direction>
                    <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                </argument>
            </argumentList>
        </action>
        <action>
            <name>Seek</name>
            <argumentList>
                <argument>
                    <name>InstanceID</name>
                    <direction>in</direction>
                    <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                </argument>
                <argument>
                    <name>Unit</name>
                    <direction>in</direction>
                    <relatedStateVariable>A_ARG_TYPE_SeekMode</relatedStateVariable>
                </argument>
                <argument>
                    <name>Target</name>
                    <direction>in</direction>
                    <relatedStateVariable>A_ARG_TYPE_SeekTarget</relatedStateVariable>
                </argument>
            </argumentList>
        </action>
        <action>
            <name>Next</name>
            <argumentList>
                <argument>
                    <name>InstanceID</name>
                    <direction>in</direction>
                    <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                </argument>
            </argumentList>
        </action>
        <action>
            <name>Previous</name>
            <argumentList>
                <argument>
                    <name>InstanceID</name>
                    <direction>in</direction>
                    <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                </argument>
            </argumentList>
        </action>
        <action>
            <name>SetPlayMode</name>
            <argumentList>
                <argument>
                    <name>InstanceID</name>
                    <direction>in</direction>
                    <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                </argument>
                <argument>
                    <name>NewPlayMode</name>
                    <direction>in</direction>
                    <relatedStateVariable>CurrentPlayMode</relatedStateVariable>
                </argument>
            </argumentList>
        </action>
        <action>
            <name>GetCurrentTransportActions</name>
            <argumentList>
                <argument>
                    <name>InstanceID</name>
                    <direction>in</direction>
                    <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                </argument>
                <argument>
                    <name>Actions</name>
                    <direction>out</direction>
                    <relatedStateVariable>CurrentTransportActions</relatedStateVariable>
                </argument>
            </argumentList>
        </action>
    </actionList>
    <serviceStateTable>
        <stateVariable sendEvents="yes">
            <name>LastChange</name>
            <dataType>string</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>TransportState</name>
            <dataType>string</dataType>
            <allowedValueList>
                <allowedValue>STOPPED</allowedValue>
                <allowedValue>PLAYING</allowedValue>
                <allowedValue>PAUSED_PLAYBACK</allowedValue>
                <allowedValue>TRANSITIONING</allowedValue>
                <allowedValue>NO_MEDIA_PRESENT</allowedValue>
            </allowedValueList>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>TransportStatus</name>
            <dataType>string</dataType>
            <allowedValueList>
                <allowedValue>OK</allowedValue>
                <allowedValue>ERROR_OCCURRED</allowedValue>
            </allowedValueList>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>PlaybackStorageMedium</name>
            <dataType>string</dataType>
            <allowedValueList>
                <allowedValue>NETWORK</allowedValue>
            </allowedValueList>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>RecordStorageMedium</name>
            <dataType>string</dataType>
            <allowedValueList>
                <allowedValue>NOT_IMPLEMENTED</allowedValue>
            </allowedValueList>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>PossiblePlaybackStorageMedia</name>
            <dataType>string</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>PossibleRecordStorageMedia</name>
            <dataType>string</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>CurrentPlayMode</name>
            <dataType>string</dataType>
            <allowedValueList>
                <allowedValue>NORMAL</allowedValue>
                <allowedValue>REPEAT_ONE</allowedValue>
                <allowedValue>REPEAT_ALL</allowedValue>
                <allowedValue>SHUFFLE</allowedValue>
                <allowedValue>SHUFFLE_REPEAT</allowedValue>
            </allowedValueList>
            <defaultValue>NORMAL</defaultValue>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>TransportPlaySpeed</name>
            <dataType>string</dataType>
            <allowedValueList>
                <allowedValue>1</allowedValue>
            </allowedValueList>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>RecordMediumWriteStatus</name>
            <dataType>string</dataType>
            <allowedValueList>
                <allowedValue>NOT_IMPLEMENTED</allowedValue>
            </allowedValueList>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>CurrentRecordQualityMode</name>
            <dataType>string</dataType>
            <allowedValueList>
                <allowedValue>NOT_IMPLEMENTED</allowedValue>
            </allowedValueList>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>PossibleRecordQualityModes</name>
            <dataType>string</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>NumberOfTracks</name>
            <dataType>ui4</dataType>
            <allowedValueRange>
                <minimum>0</minimum>
                <maximum>1</maximum>
            </allowedValueRange>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>CurrentTrack</name>
            <dataType>ui4</dataType>
            <allowedValueRange>
                <minimum>0</minimum>
                <maximum>1</maximum>
                <step>1</step>
            </allowedValueRange>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>CurrentTrackDuration</name>
            <dataType>string</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>CurrentMediaDuration</name>
            <dataType>string</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>CurrentTrackMetaData</name>
            <dataType>string</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>CurrentTrackURI</name>
            <dataType>string</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>AVTransportURI</name>
            <dataType>string</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>AVTransportURIMetaData</name>
            <dataType>string</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>NextAVTransportURI</name>
            <dataType>string</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>NextAVTransportURIMetaData</name>
            <dataType>string</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>RelativeTimePosition</name>
            <dataType>string</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>AbsoluteTimePosition</name>
            <dataType>string</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>RelativeCounterPosition</name>
            <dataType>i4</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>AbsoluteCounterPosition</name>
            <dataType>i4</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>CurrentTransportActions</name>
            <dataType>string</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>A_ARG_TYPE_SeekMode</name>
            <dataType>string</dataType>
            <allowedValueList>
                <allowedValue>TRACK_NR</allowedValue>
                <allowedValue>REL_TIME</allowedValue>
            </allowedValueList>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>A_ARG_TYPE_SeekTarget</name>
            <dataType>string</dataType>
        </stateVariable>
        <stateVariable sendEvents="no">
            <name>A_ARG_TYPE_InstanceID</name>
            <dataType>ui4</dataType>
        </stateVariable>
    </serviceStateTable>
</scpd>

@alexballas
Copy link
Owner

Thank you for that. I compiled a debug version of Go2TV for Linux. Would it be possible to run it from a terminal (in GUI mode), try to cast your file again and send me the output of the terminal.
Just added some extra logging to the HTTP request / responses.

go2tv.zip

I should probably add a debug flag in future releases too.

@Mikescops
Copy link
Contributor Author

Mikescops commented Jun 7, 2022

Here is the answer:

Click to expand
REQUEST:  <?xml version='1.0' encoding='utf-8'?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <s:Body>
    <u:SetAVTransportURI xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
      <InstanceID>0</InstanceID>
      <CurrentURI>http://192.168.1.85:3500/output.flac</CurrentURI>
      <CurrentURIMetaData>
        <DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"
          xmlns:dc="http://purl.org/dc/elements/1.1/"
          xmlns:sec="http://www.sec.co.kr/"
          xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/">
          <item restricted="false" id="0" parentID="-1">
            <sec:CaptionInfo sec:type="srt">http://192.168.1.85:3500/.</sec:CaptionInfo>
            <sec:CaptionInfoEx sec:type="srt">http://192.168.1.85:3500/.</sec:CaptionInfoEx>
            <upnp:class>object.item.audioItem.musicTrack</upnp:class>
            <dc:title>output.flac</dc:title>
            <res protocolInfo="http-get:*:audio/x-flac:*">http://192.168.1.85:3500/output.flac</res>
            <res protocolInfo="http-get:*:text/srt:*">http://192.168.1.85:3500/.</res>
          </item>
        </DIDL-Lite>
      </CurrentURIMetaData>
    </u:SetAVTransportURI>
  </s:Body>
</s:Envelope>
RESPONSE:  <?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <s:Body>
    <s:Fault>
      <faultcode>s:Client</faultcode>
      <faultstring>UPnPError</faultstring>
      <detail>
        <UPnPError xmlns="urn:schemas-upnp-org:control-1-0">
          <errorCode>501</errorCode>
          <errorDescription>Action SetAVTransportURI failed
          </errorDescription>
        </UPnPError>
      </detail>
    </s:Fault>
  </s:Body>
</s:Envelope> 500 Internal Server Error
REQUEST:  <?xml version='1.0' encoding='utf-8'?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <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>
RESPONSE:  <?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <s:Body>
    <s:Fault>
      <faultcode>s:Client</faultcode>
      <faultstring>UPnPError</faultstring>
      <detail>
        <UPnPError xmlns="urn:schemas-upnp-org:control-1-0">
          <errorCode>701</errorCode>
          <errorDescription>Action Play failed
          </errorDescription>
        </UPnPError>
      </detail>
    </s:Fault>
  </s:Body>
</s:Envelope> 500 Internal Server Error

Edit: I also confirm that http://192.168.1.85:3500/output.flac is properly served.

@alexballas
Copy link
Owner

alexballas commented Jun 7, 2022

Thank you. That's a hard one to get to the bottom of given that I dont have the device to run various checks. What I can do, is provide a version of Go2TV later in the day where I remove the SecCaption items from the request (and anything subtitle related that sits there by default) and see if that helps.

@Mikescops
Copy link
Contributor Author

Ok sure, let's do this 😄

@alexballas
Copy link
Owner

Ty. Could you please test this version and see if it make a difference? Usually the mitigation step for those 501 errors is to retry, which in our case does not work.
go2tv_2.zip

@Mikescops
Copy link
Contributor Author

Mikescops commented Jun 7, 2022

Nope, not working either, same error...

Click
REQUEST:  <?xml version='1.0' encoding='utf-8'?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:SetAVTransportURI xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><CurrentURI>http://192.168.1.85:3500/toto.flac</CurrentURI><CurrentURIMetaData>&lt;DIDL-Lite xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sec="http://www.sec.co.kr/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/"&gt;&lt;item restricted="false" id="0" parentID="-1"&gt;&lt;upnp:class&gt;object.item.audioItem.musicTrack&lt;/upnp:class&gt;&lt;dc:title&gt;toto.flac&lt;/dc:title&gt;&lt;res protocolInfo="http-get:*:audio/x-flac:*"&gt;http://192.168.1.85:3500/toto.flac&lt;/res&gt;&lt;/item&gt;&lt;/DIDL-Lite&gt;</CurrentURIMetaData></u:SetAVTransportURI></s:Body></s:Envelope>
RESPONSE:  <?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><s:Fault><faultcode>s:Client</faultcode><faultstring>UPnPError</faultstring><detail><UPnPError xmlns="urn:schemas-upnp-org:control-1-0"><errorCode>501</errorCode><errorDescription>Action SetAVTransportURI failed

@alexballas
Copy link
Owner

OK, not unexpected. From a quick search it seems that your speaker work fine with BubbleUPNP on android. I'll try to reverse engineer the calls and see if there are any discrepancies. Keeping the ticket open as there are certainly improvements to introduce to the UPNP protocol implementation.

@Mikescops
Copy link
Contributor Author

This bridge to LMS by @philippe44 is also working well: https://github.com/philippe44/LMS-to-uPnP
(except that the playlist is stuck when pushing the next uri but I guess it'll be solved)

I'll also take a look to your code to see if I can make it work (if I find enough time) 👍

@alexballas
Copy link
Owner

alexballas commented Jun 8, 2022

So I did a bit of investigation and tested both BubbleUPNP & the bridge to LMS
In both cases I used flac files

BubbleUPNP

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<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>http://192.168.88.253:57645/external/audio/media/186608.flac</CurrentURI>
			<CurrentURIMetaData>
				<DIDL-Lite
					xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"
					xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/"
					xmlns:dc="http://purl.org/dc/elements/1.1/"
					xmlns:dlna="urn:schemas-dlna-org:metadata-1-0/"
					xmlns:sec="http://www.sec.co.kr/"
					xmlns:pv="http://www.pv.com/pvns/">
					<item id="parent/186608" parentID="parent" restricted="1">
						<upnp:class>object.item.audioItem.musicTrack</upnp:class>
						<dc:title>Symphony No.6 (1st movement)</dc:title>
						<dc:creator>Ludwig van Beethoven</dc:creator>
						<upnp:artist>Ludwig van Beethoven</upnp:artist>
						<upnp:albumArtURI>http://192.168.88.253:57645/external/audio/albums/32.jpg</upnp:albumArtURI>
						<upnp:genre>Classical</upnp:genre>
						<upnp:album>www.mfiles.co.uk</upnp:album>
						<res protocolInfo="http-get:*:audio/flac:DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01700000000000000000000000000000" bitsPerSample="16" bitrate="71416" sampleFrequency="44100" nrAudioChannels="2" size="51997326" duration="0:12:08.000">http://192.168.88.253:57645/external/audio/media/186608.flac</res>
					</item>
				</DIDL-Lite>
			</CurrentURIMetaData>
		</u:SetAVTransportURI>
	</s:Body>
</s:Envelope>

bridge to LMS

<s:Envelope
	xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
	<s:Body>
		<u:SetAVTransportURI
			xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
			<InstanceID>0</InstanceID>
			<CurrentURI>http://192.168.88.250:59955/bridge-4.flac</CurrentURI>
			<CurrentURIMetaData>
				<DIDL-Lite
					xmlns:dc="http://purl.org/dc/elements/1.1/"
					xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/"
					xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"
					xmlns:dlna="urn:schemas-dlna-org:metadata-1-0/">
					<item id="1" parentID="0" restricted="1">
						<dc:title>Innocence</dc:title>
						<dc:creator>Hoff Ensemble: Jan Gunnar Hoff, Audun Kleive &amp;amp; Anders Jormin</dc:creator>
						<upnp:genre>Jazz</upnp:genre>
						<upnp:artist>Hoff Ensemble: Jan Gunnar Hoff, Audun Kleive &amp;amp; Anders Jormin</upnp:artist>
						<upnp:album>POLARITY ... an acoustic jazz project</upnp:album>
						<upnp:originalTrackNumber>1</upnp:originalTrackNumber>
						<upnp:albumArtURI>http://192.168.88.250:9000/music/46b89aec/cover_.jpg</upnp:albumArtURI>
						<upnp:class>object.item.audioItem.musicTrack</upnp:class>
						<res duration="0:05:07.293" protocolInfo="http-get:*:audio/x-flac:DLNA.ORG_OP=00;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=09700000000000000000000000000000">http://192.168.88.250:59955/bridge-4.flac</res>
					</item>
				</DIDL-Lite>
			</CurrentURIMetaData>
		</u:SetAVTransportURI>
	</s:Body>
</s:Envelope>

and this is the Go2TV example you provided above

<?xml version='1.0' encoding='utf-8'?>
<s:Envelope
	xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
	<s:Body>
		<u:SetAVTransportURI
			xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
			<InstanceID>0</InstanceID>
			<CurrentURI>http://192.168.1.85:3500/toto.flac</CurrentURI>
			<CurrentURIMetaData>
				<DIDL-Lite
					xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"
					xmlns:dc="http://purl.org/dc/elements/1.1/"
					xmlns:sec="http://www.sec.co.kr/"
					xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/">
					<item restricted="false" id="0" parentID="-1">
						<upnp:class>object.item.audioItem.musicTrack</upnp:class>
						<dc:title>toto.flac</dc:title>
						<res protocolInfo="http-get:*:audio/x-flac:*">http://192.168.1.85:3500/toto.flac</res>
					</item>
				</DIDL-Lite>
			</CurrentURIMetaData>
		</u:SetAVTransportURI>
	</s:Body>
</s:Envelope>

The biggest difference is in the "res protocolInfo" element where I dont pass the extra flags. I thought that this was optional given that the same flags are being served as headers by the webserver as seen here https://github.com/alexballas/go2tv/blob/main/httphandlers/httphandlers.go#L273
The fact that this is optional is also backed by the ContentDirectory specification [here|https://openconnectivity.org/wp-content/uploads/2015/11/UPnP-av-ContentDirectory-v4-Service-20150319.pdf]

Furthermore according to the specification upnp:genre / upnp:album etc should be optional.
Same for res duration.

I also went through the DIDL-LITE xsd schema uploaded here and there is snippet that says

In all cases, the first element in each item child element
sequence is required to be "dc:title".
The 'upnp:class' element must also appear under item.

Which is respected by the Bridge but not BubbleUPNP

In the Go2TV example <item restricted="false" id="0" parentID="-1"> seems to be different but according to the XSD "false" is acceptable. Also there seems to be no restriction on the sequence of items like for the dc:title.

For <?xml version='1.0' encoding='utf-8'?> I used single quotes (which should be fine)

TL/DR:

I really don't understand where things go wrong. The UPNP protocol is so loosely integrated by the vendors that things never are consistent across devices. However, I did push some changes to the devel branch to better match the other applications.
Now when I serve flacs it looks like this

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope
	xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
	<s:Body>
		<u:SetAVTransportURI
			xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
			<InstanceID>0</InstanceID>
			<CurrentURI>http://192.168.88.250:3500/2L-45_stereo_01_FLAC_88k_24b.flac</CurrentURI>
			<CurrentURIMetaData>
				<DIDL-Lite
					xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"
					xmlns:dc="http://purl.org/dc/elements/1.1/"
					xmlns:sec="http://www.sec.co.kr/"
					xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/">
					<item id="1" parentID="0" restricted="1">
						<dc:title>2L-45_stereo_01_FLAC_88k_24b.flac</dc:title>
						<upnp:class>object.item.audioItem.musicTrack</upnp:class>
						<res protocolInfo="http-get:*:audio/x-flac:DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000">http://192.168.88.250:3500/2L-45_stereo_01_FLAC_88k_24b.flac</res>
					</item>
				</DIDL-Lite>
			</CurrentURIMetaData>
		</u:SetAVTransportURI>
	</s:Body>
</s:Envelope>

What I didn't include is the "duration" element which was a common thing for both BubbleUPNP & the bridge to LMS. First I'd like to see if those changes make any difference and if not I'll give the duration a go. My main concern with duration is how to support multiple media files and the only proper way to do it is with ffmpeg.

Here is a compiled version for linux: go2tv_3.zip
Please test if you can with GUI mode since I didn't thoroughly check the CLI mode.

@Mikescops
Copy link
Contributor Author

I'm so sorry but it stills not working 😢

@Mikescops
Copy link
Contributor Author

Mikescops commented Jun 8, 2022

I made some tests using Postman, and I got the same error with the 3 different payloads.

I'll have to capture the calls on my side then.

EDIT1:
So I captured my network to get the exact payload sent by the LMS bridge and tried to replay it, and I can't make it work.

curl --location --request POST 'http://192.168.1.32:54380/upnp/control/AVTransport' \
--header 'Content-Type: text/xml; charset="utf-8"' \
--header 'SOAPAction: "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI"' \
--header 'Connection: Keep-Alive' \
--header 'User-Agent: toto' \
--header 'Host: 192.168.1.32:54380' \
--data-raw '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
        <u:SetAVTransportURI xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
            <InstanceID>0</InstanceID>
            <CurrentURI>http://192.168.1.85:3500/output.flac</CurrentURI>
            <CurrentURIMetaData>&lt;DIDL-Lite xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:upnp=&quot;urn:schemas-upnp-org:metadata-1-0/upnp/&quot; xmlns=&quot;urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/&quot; xmlns:dlna=&quot;urn:schemas-dlna-org:metadata-1-0/&quot;&gt;&lt;item id=&quot;1&quot; parentID=&quot;0&quot; restricted=&quot;1&quot;&gt;&lt;dc:title&gt;Du propre&lt;/dc:title&gt;&lt;dc:creator&gt;Orelsan, Skread&lt;/dc:creator&gt;&lt;upnp:genre&gt;&lt;/upnp:genre&gt;&lt;upnp:artist&gt;Orelsan, Skread&lt;/upnp:artist&gt;&lt;upnp:album&gt;Civilisation&lt;/upnp:album&gt;&lt;upnp:originalTrackNumber&gt;0&lt;/upnp:originalTrackNumber&gt;&lt;upnp:class&gt;object.item.audioItem.musicTrack&lt;/upnp:class&gt;&lt;res duration=&quot;0:03:27.000&quot; protocolInfo=&quot;http-get:*:audio/flac:DLNA.ORG_OP=00;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=09700000000000000000000000000000&quot;&gt;http://192.168.1.85:3500/output.flac&lt;/res&gt;&lt;/item&gt;&lt;/DIDL-Lite&gt;</CurrentURIMetaData>
        </u:SetAVTransportURI>
    </s:Body>
</s:Envelope>
'

The result is still an error 501 and I can't find what it means 👎

<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
        <s:Fault>
            <faultcode>s:Client</faultcode>
            <faultstring>UPnPError</faultstring>
            <detail>
                <UPnPError xmlns="urn:schemas-upnp-org:control-1-0">
                    <errorCode>501</errorCode>
                    <errorDescription>Action SetAVTransportURI failed
</errorDescription>
                </UPnPError>
            </detail>
        </s:Fault>
    </s:Body>
</s:Envelope>

EDIT2: i can't find what's wrong...

EDIT3: i'm starting to think this is due to how the audio file is served, not the soap request... Some header might be wrong like the contentFeatures.dlna.org.

@alexballas
Copy link
Owner

Ty for that. Would it be possible to grab the headers when using the proxy with Wireshark? Also could you please share the protocol info of you Sony's? You can grab that with this script here https://github.com/alexballas/dlnaprotocolinfo. Unfortunately I only compiled it for windows.

@Mikescops
Copy link
Contributor Author

Mikescops commented Jun 9, 2022

So getting the packets during #SetAVTransportURI I have:

HEAD /bridge-1.flac HTTP/1.1
getcontentFeatures.dlna.org: 1
Host: 192.168.1.85:47143

HTTP/1.1 200 OK
Server: squeezebox-bridge
Connection: close
Content-Type: audio/flac
contentFeatures.dlna.org: DLNA.ORG_OP=00;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=09700000000000000000000000000000

Then I tested to #Stop and #Play again:

HEAD /bridge-1.flac HTTP/1.1
Host: 192.168.1.85:47143
Accept: */*
X-AV-Physical-Unit-Info: pa="HT-A9"
X-AV-Client-Info: av="5.0"; cn="Sony Corporation"; mn="HT-A9"; mv="0.01";
transferMode.dlna.org:Streaming
getcontentFeatures.dlna.org: 1

HTTP/1.1 200 OK
Server: squeezebox-bridge
Connection: close
Content-Type: audio/flac
transferMode.dlna.org: Streaming
contentFeatures.dlna.org: DLNA.ORG_OP=00;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=09700000000000000000000000000000

I built your go tool for linux and i got this:

Linux/2.6 UPnP/1.0 HT-A9/0.01
<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><s:Fault><faultcode>s:Client</faultcode><faultstring>UPnPError</faultstring><detail><UPnPError xmlns="urn:schemas-upnp-org:control-1-0"><errorCode>501</errorCode><errorDescription>Action Failed</errorDescription></UPnPError></detail></s:Fault></s:Body></s:Envelope>
----------

😭

EDIT:

I played a bit with Postman and found out the issue:

It should be s:encodingStyle in the request and not just encodingStyle:

<?xml version='1.0' encoding='utf-8'?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:GetProtocolInfo xmlns:u="urn:schemas-upnp-org:service:ConnectionManager:1"></u:GetProtocolInfo></s:Body></s:Envelope>

So the reply is :

<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
        <u:GetProtocolInfoResponse xmlns:u="urn:schemas-upnp-org:service:ConnectionManager:1">
            <Source></Source>
            <Sink>http-get:*:audio/L16:DLNA.ORG_PN=LPCM;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3X;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMABASE;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMAFULL;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/vnd.dlna.adts:DLNA.ORG_PN=AAC_ADTS;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/vnd.dlna.adts:DLNA.ORG_PN=AAC_ADTS_192;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/vnd.dlna.adts:DLNA.ORG_PN=AAC_ADTS_320;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/mp4:DLNA.ORG_PN=AAC_ISO;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/3gpp:DLNA.ORG_PN=AAC_ISO;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/mp4:DLNA.ORG_PN=AAC_ISO_192;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/3gpp:DLNA.ORG_PN=AAC_ISO_192;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/mp4:DLNA.ORG_PN=AAC_ISO_320;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/3gpp:DLNA.ORG_PN=AAC_ISO_320;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/vnd.dlna.adts:DLNA.ORG_PN=AAC_MULT5_ADTS;DLNA.ORG_FLAGS=9d700000000000000000000000000000,http-get:*:audio/mp4:DLNA.ORG_PN=AAC_MULT5_ISO;DLNA.ORG_FLAGS=9d700000000000000000000000000000,http-get:*:audio/3gpp:DLNA.ORG_PN=AAC_MULT5_ISO;DLNA.ORG_FLAGS=9d700000000000000000000000000000,http-get:*:audio/vnd.dlna.adts:DLNA.ORG_PN=HEAAC_L2_ADTS;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/mp4:DLNA.ORG_PN=HEAAC_L2_ISO;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/3gpp:DLNA.ORG_PN=HEAAC_L2_ISO;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/vnd.dlna.adts:DLNA.ORG_PN=HEAAC_L2_ADTS_320;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/mp4:DLNA.ORG_PN=HEAAC_L2_ISO_320;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/3gpp:DLNA.ORG_PN=HEAAC_L2_ISO_320;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/mp4:DLNA.ORG_PN=HEAAC_L2_ISO_128;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/3gpp:DLNA.ORG_PN=HEAAC_L2_ISO_128;DLNA.ORG_FLAGS=9d300000000000000000000000000000,http-get:*:audio/mpeg:*,http-get:*:audio/L16:*,http-get:*:audio/wav:*,http-get:*:audio/x-wav:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/mp4:*,http-get:*:audio/3gpp:*,http-get:*:audio/vnd.dlna.adts:*,http-get:*:audio/flac:*,http-get:*:audio/x-flac:*,http-get:*:audio/aiff:*,http-get:*:audio/x-aiff:*,http-get:*:audio/aif:*,http-get:*:audio/x-aif:*,http-get:*:audio/m4a:*,http-get:*:audio/x-m4a:*,http-get:*:audio/x-alac:*,http-get:*:audio/ogg:*,http-get:*:audio/x-ogg:*,http-get:*:audio/x-monkeys-audio:*,http-get:*:audio/ape:*,http-get:*:audio/x-ape:*,http-get:*:audio/dsd:*,http-get:*:audio/x-dsd:*</Sink>
        </u:GetProtocolInfoResponse>
    </s:Body>
</s:Envelope>

Sounds like there is the expected http-get:*:audio/flac:*

@Mikescops
Copy link
Contributor Author

Can you push your branch with the debug logs? I'm trying to find out what's going on (tho' I never did golang x) )

@alexballas
Copy link
Owner

alexballas commented Jun 9, 2022

Hey, apologies for the delay. Due to health reasons I won't be able to write any code / access a PC for a couple of days, but I'm available through my phone. Regarding the content features, this is something that go2tv also sets. The supported DLNA ORG_FLAGS can be checked with the other app I shared.

Edit: apologies, I miss clicked and resolved the ticket. Reopened it

@alexballas alexballas reopened this Jun 9, 2022
@Mikescops
Copy link
Contributor Author

Oh, so sorry to hear that, get better soon! I'll try to investigate more, but I never seen such weird issue :(

@Mikescops
Copy link
Contributor Author

Mikescops commented Jun 10, 2022

So I finally found what's happening, and it's because we didn't push the media type in the headers, so the player was lost somehow.

Now that this is fixed, there is another issue, the sound starts playing but stops after a few seconds.

When looking at the network, it seems that the player sends a STOPPED event (which triggers an unsubscribe from go2tv) right after we set the transportURI.

Screenshot_20220610_100356

Once again I have no idea why the player is doing this, but I'll take a look.

EDIT:
I checked on the LMS behavior and it seems that the player is also sending right away the stop event (a bug maybe?), and LMS just like here is unsubscribing (which likely causes errors later, like for going to the next uri when time is over).

In go2tv case what happens when the stop even is received is that we emit screen.EmitMsg("Stopped") and this updates the UI but also calls stopAction(p) which itself calls screen.httpserver.StopServer() then we don't have anymore the file stream so the player can't render any audio.

I tried to ignore the stop message at the beginning and it works well. Problem is that it won't fit most players because I still think that's an issue coming from this model.

EDIT2: I filled in a support ticket on Sony's help center.

@alexballas
Copy link
Owner

Apologies I'm still on phone but I think I can answer most of it. First of all a big thank you for the stellar analysis! When I can, I'll check the integration documents again to confirm if the file type in the header is optional or not. I'll add it off since it works for you. As for the Stop that it sends right away, it's not the first time I Ve seen it. My Samsung tv also do it. Check my code comment here:

// Apparently we should ignore the first message

Does the sound stop after a while with all files types? Mp3s also?

@Mikescops
Copy link
Contributor Author

Yes, it's consistent over file types. If you have a closer look, you'll see that the STOPPED notify is the second notify, there is a first one that just announces the track:

<?xml version="1.0"?><e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0"><e:property><LastChange>&lt;Event xmlns=&quot;urn:schemas-upnp-org:metadata-1-0/AVT/&quot;&gt;
  &lt;InstanceID val=&quot;0&quot;&gt;
    &lt;CurrentTrack val=&quot;0&quot;/&gt;
  &lt;/InstanceID&gt;
&lt;/Event&gt;
</LastChange></e:property></e:propertyset>

I also spotted an issue where you try to update the state even for messages that are not state updates. I decided to ignore only the first STOPPED event then (it shouldn't impact players that do not have this behavior).

So the following happens on the seq variable:

0 // ignored (not state update)
0 STOPPED // first stopped  event happening with seq==0 so we seq++ and ignore the event
1 // ignored (not state update)
1 TRANSITIONING
2 PLAYING

See the following PRs:

NEW BUG
Hitting the pause button does nothing, I'll take a look 😄

@alexballas
Copy link
Owner

alexballas commented Jun 10, 2022

Had a quick looks at the STOPPED PR. When I first saw this behaviour in one of my devices I didn't know if it's a bug In the client or something is should consider as part of the code. So what I did was to introduce a call sequence ID to block the first call and potentially use this info in the future for something else. If you see, this is the only place where sequence id is used. In theory we can only add a check inside UpdateMRstate that check if previous state == "" and newstate == "STOPPED" to return false.

@Mikescops
Copy link
Contributor Author

Thing is previousstate from the device request is populated at "Play", but this is doable by taking the previous state from the local saved state.

Both ways work well, I agree that storing the sequence ID is also interesting. Let me know what you prefer I'll update the code.

@alexballas
Copy link
Owner

alexballas commented Jun 11, 2022

Would it be possible to check something for me? Is the sequence of notifications

  • track announcement
  • stop
  • play ?

If yes, the we can do the following
In type States struct add a bool field and name it something like processStop.
In the code, whenever we receive a notification, only process the STOP actions if processStop is true. We can only set processStop = true if we receive a Play (or PAUSE in case the PLAY gets lost) notification. The rest of the notifications can be progresses regardless of the bool value.

The sequence code can be scrapped

@alexballas
Copy link
Owner

Screenshot_20220611-105423

@Mikescops
Copy link
Contributor Author

Yes I confirm that's the case, I updated the PR.

@alexballas
Copy link
Owner

alexballas commented Jun 11, 2022

Ty! I'll have a look. Can you please confirm that the two PR now fully resolve the issues with your Sonys?
If yes, did you test with the main branch or develop?

@Mikescops
Copy link
Contributor Author

There is still an issue with the pause action but should be fine for now. I based on master.

@alexballas
Copy link
Owner

That's good, thank you! Worth raising a new defect for the pause one. Similarly to your investigation here, we would need to see what responses Sonys send with the pause action.

@Mikescops
Copy link
Contributor Author

Yes, I think there is room for improvement in the way the code is organized. Because some calls to the TV are made directly from the gui folder and it's difficult to understand what exactly is called when you receive an event or emit one.

@alexballas
Copy link
Owner

alexballas commented Jun 11, 2022

Understood. The idea behind emmit messages is for each UI to implement the screen interface https://github.com/alexballas/go2tv/blob/main/httphandlers/httphandlers.go#L31. It should then be up to the UI to process those notification callbacks and decide how to further control the UI flow. In theory you can have a UI that does not deal at all with the notifications the DMR sends. This is a transparent process for the http handler that pushes those notifications.

@alexballas
Copy link
Owner

alexballas commented Jun 18, 2022

So I finally found what's happening, and it's because we didn't push the media type in the headers, so the player was lost somehow.

So I had a deeper look at the content type and in my tests I got
Screenshot from 2022-06-18 10-40-46
From here I see that the headers were already passed correctly when trying to stream an audio file.

same for a flac file

Accept-Ranges: bytes
Content-Length: 336902264
Content-Type: audio/flac
content-type: audio/x-flac <------------------ this is after your PR
Date: Sat, 18 Jun 2022 07:45:56 GMT
Last-Modified: Sun, 29 Jul 2018 16:14:56 GMT
realTimeInfo.dlna.org: DLNA.ORG_TLAG=*
transferMode.dlna.org: Streaming

Just trying to understand if this indeed the issue

EDIT:
I think it's just the HEAD requests suffering from this. Will rework the fix to avoid the double headers

EDIT2:
Amended here: 89154bc

@Mikescops
Copy link
Contributor Author

Nice catch!

@alexballas
Copy link
Owner

Fixed with 1.12.0, resolving

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants