Closed microrache closed 6 months ago
Mixcloud doesn't have an official way to stream music via other devices. The plugin uses an external "downloader" site to get a streamable URL. Currently this is https://www.savelink.info/ That site doesn't seem to be working for Mixcloud at the moment. It might be that functionality is restored at some point by that site, and then this plugin will also work again. If not, and it takes a long time, I might have to look for another service (again). If you know of a Mixcloud download website that is working, I can see if it can be used by this plugin.
I'm a huge fan of mixcloud and very grateful for your work on this @danielvijge .
I am curious why the third party site is needed. Can you outline the technical (or other?) challenges identifying the streaming endpoint from mixcloud.com directly?
To interact with a service, such as Mixcloud, often an API (application programming interface) is used. This is a way for applications (whether a mobile app, website, TV, or a Squeezebox plugin) to interact with a service and request (get) information, or send information (post). Mixcloud has such an API, and all the details are published at https://www.mixcloud.com/developers/ There are API methods to search, follow, upload, etc. However, under streaming Mixcloud states:
The audio streams are not available through the Mixcloud API. There are two reasons for this.
Firstly, we need to know what has been listened to so that we can report usage, pay royalties and provide features such as 'Suggested Shows'.Secondly, Mixcloud needs to pay the bills! We can't give away the audio for free outside of mixcloud.com simply because it costs us to host and stream the files and pay royalties.
Of course there is the official app and website, which do stream audio. People have reverse engineered how this works. This is exactly what websites like savelink do. There are more similar websites, and applications like youtube-dl. Relying on a third-party service for this allow this plugin to be a lot simpler, as it doesn't need all that reverse engineering code.
But sometimes the third-partry service breaks, or Mixcloud changes something that breaks things. In such cases this plugin is also broken until the method to play Mixcloud tracks externally is reverse engineered again.
I guess it's up to everyone to decide if you think it's justified to play Mixcloud tracks in this way if Mixcloud doesn't want to offer it like this.
I ran into this a few days ago and made a quick patch to the Mixcloud plugin to obtain the stream url by invoking yt-dlp (a youtube-dl fork).
yt-dlp produces a json of several stream options - one conventional http mp3/m4a encoded audio and several HLS and DASH options. LMS is able to play the http stream natively, unfortunately the bitrate is quite low compared to the other options.
I'm planning on expanding on this and having LMS play the highest bitrate HLS stream using the PlayHLS plugin. I'm happy to send a PR for that once I have something worthwhile, thanks for your work maintaining this project @danielvijge
(crossposted from the forum)
Indeed things like yt-dl (or a fork) would work, and make the plugin less dependent on am external service. Bit it would also complicate the installation a bit. Either users would have to manually install yt-dl, or the plugin would need to distribute a copy. But that would then require different versions for Windows/MacOS/Linux i384/arm/etc.
There are two github repos i experimented with. The first is a very alpha thing that I didn't continue with further: https://github.com/danielvijge/squeezebox-cloudplay It would potentially allow to play any stream supported by yt-dl, and I had the thought of using yt-dl's update command to update binary independent of the plugin.
The other option is to host a cloud service of yt-dl just for this plugin. An AWS lambda is available in https://github.com/danielvijge/youtu...ct-info-lambda But hosting that, and having the plugin use it, might be a bit of a risk for me. I have no idea how many people use the Mixcloud plugin, so what the costs might be of hosting it. And I cannot limit it to just this plugin; it would be publicly accessible for everyone. And on top of the costs there might be the legal risk of hosting this is a public service.
If you know of a Mixcloud download website that is working, I can see if it can be used by this plugin.
I came across https://mixclouddownloader.net/download-track which might slot in better than yt-dl ?
@internoot I'm indeed trying to incorporate your patch into a new release, bundling the yt-dlp binary for each platform. Maybe I don't fully understand the plugin I maintain, but with yt-dlp I indeed get an m4a steam URL, but then an error message
Slim::Player::Squeezebox2::statHandler (156) Error: Decoder does not support file format, code 0
Did you install/configure anything else to decode the file format?
A possible fix uses yt-dlp has been added in a16c752046243a247d1ad6de95473b6f1b3700d0 The first development version that uses this is version 0.10.1. If the dev repo is added to LMS, this version can be installed.
Being able to play all files also requires https://github.com/LMS-Community/slimserver/pull/1056 to be merged. Some newer files on Mixcloud use an mp4 format that could not be streamed directly by LMS.
Released https://github.com/danielvijge/lms_mixcloud/releases/tag/0.11 to resolve the issue
Tested 0.11 this morning. It works great! Your contribution to the quality of my life is significant and I really appreciate it!
One minor issue for me: I use the official LMS container from here: https://hub.docker.com/r/lmscommunity/logitechmediaserver . The issue appeared in my log file as:
[24-04-19 07:26:51.1964] Slim::Player::Song::open (424) Error: Couldn't create command line for unk playback for [mixcloud://alucidnation/eclectronica-show-82/]
[24-04-19 07:27:06.1909] Plugins::MixCloud::ProtocolHandler::_fetchTrackExtra (250) Failed to determine stream URL for mixcloud://alucidnation/eclectronica-show-82/
[24-04-19 07:27:06.1920] Plugins::MixCloud::ProtocolHandler::_fetchTrackExtra (251) Tried to execure command: /config/cache/InstalledPlugins/Plugins/MixCloud/Bin/yt-dlp --skip-download --dump-json https://www.mixcloud.com/alucidnation/eclectronica-show-82/ 2>&1
[24-04-19 07:27:06.1985] Plugins::MixCloud::ProtocolHandler::_fetchTrackExtra (252) /usr/bin/env: âpython3â: No such file or directory
The problem was that the container does not include python3... so the solution was to install python3 in the container, something like this:
podman exec -it logitechmediaserver /bin/bash
# apt install python3
@richardhenwood One the forum the same problem was mentioned as well. If you dont' want to go installing python everytime you pull a new version of the container, you can use a version of yt-dlp
with bundled python3:
just dropping by to say thanks for this fix, much appreciated
Many thanks for getting this back working!
I was wondering if there was a way to play the HQ feed if it is available? e.g. this link was uploaded in HQ (192kb) https://www.mixcloud.com/NTSRadio/150-session-cycladic-figurines-11th-may-2024/
but it plays at 64kb;
File Format: MPEG-4
Duration: 59:52
Bitrate: 64kbps CBR
Sample Rate: 44.1 kHz
Sample Size: 16Bits
URL: mixcloud://NTSRadio/150-session-cycladic-figurines-11th-may-2024/
Examining the output from
yt-dlp --skip-download --dump-json https://www.mixcloud.com/NTSRadio/150-session-cycladic-figurines-11th-may-2024/
shows streams which are suffixed with "-192K".
I've tried modifying the plugin to get it to play these but I don't really know much about Perl :(
@austin99 First thing you could try is to copy url
from that stream into "Radio > Tune In URL" and see if it works.
If I don't mix two things up now... I think it didn't work work. It's a m8u file, so technically a playlist of multiple files and not a single file. And when LMS tries to retrieve a single entry for the playlist, Mixcloud blocks the request because "iTunes" appears in the User-Agent string of the request.
I'm sure both can be addressed, but I haven't looked into it at all.
Mixcloud is rejecting the request with a 403 forbidden, so it sounds like it could be like User-Agent parameter that is causing the rejection
Error: Can't connect to remote server to retrieve playlist for, https://audio13.mixcloud.com/secure/hls/a/2/3/7/9fd7-e5d9-486f-82c3-051368bd55be-192K.m4a/streamindex-a1.m3u8: 403 Forbidden.
That url plays ok using VLC Media Player. Also I'm using LMS 8.5.2 btw. I also have the PlayHLS v2.12 plugin installed
--
Update: It's definitely the User-Agent string;
curl -H "User-Agent: iTunes/4.7.1 (Linux; N; piCore; aarch64-linux; EN_GB; utf8) SqueezeCenter, Squeezebox Server, Logitech Media Server/8.5.2/1716215514" https://audio13.mixcloud.com/secure/hls/a/2/3/7/9fd7-e5d9-486f-82c3-051368bd55be-192K.m4a/streamindex-a1.m3u8
returns a 403 Forbidden. Changing the User-Agent to anything else and it works.
I can see that string is built in Slim::Utils::Misc::userAgentString()
but I don't think there's a hook available to alter it :(
Thank you for developing this plugin. Unfortunately, it seems that it is currently broken - I cannot play any mixes anymore. This is what is shown in the Server-logs:
[24-03-29 10:29:58.8733] Plugins::MixCloud::ProtocolHandler::__ANON__ (214) Empty response for play URL for mixcloud://angstpop/ebm-classxmix/{ error => "ERROR: URL not supported. We will investigate.", url => "https://www.mixcloud.com/angstpop/ebm-classxmix/", } [24-03-29 10:29:58.8750] Slim::Player::Song::open (424) Error: Couldn't create command line for unk playback for [mixcloud://angstpop/ebm-classxmix/]
Tried with Logitech Media Server 8.4.0 and Mixcloud v0.10
Could you confirm the issue and hopefully fix it with a new release?