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

Follow metadata in time from CUE or JSON files #3

Open
daslicht opened this issue Mar 23, 2013 · 17 comments
Open

Follow metadata in time from CUE or JSON files #3

daslicht opened this issue Mar 23, 2013 · 17 comments
Milestone

Comments

@daslicht
Copy link

Hello is it feasible to create a Radio Station only with DeeFuzzer which have the following features:
Stream seamless prerecorded DJ Mixes which are essentially one BIG audio
file and provide the listener with Song Information. (for each song in the mix)

I have tried different approaches like Icecast / Shoutcast.
Just playing a Playlist with files or with crossfades is not good enough.
(always audible glitches especially if you have a continious 4/4 trance
beat)
The only really seamless solution I have found so far, was using Icecast
and foobar2000 (the only cue-sheet player i have found and it is for
windows!) + edcast dsp (no longer maintained?) playing a cue sheet wich
contains the necessary Song Information.

To display the metadata on a webpage I have parsed the audio stream with
nodejs and pushed the songinfo via socketio to a htm5 based client.

While this approach is "working" I am looking for something more solid.

Can you use cuesheets (or something similar) with DeeFuzzer
Regards
Marc

@yomguy
Copy link
Owner

yomguy commented Mar 23, 2013

Hi,

DeeFuzzer can stream playlist in alphanumeric or random order.
It can NOT crossfade anything between cues as is it designed to be VERY light and stable (near zero CPU load), streaming audio or video files as they are in scalable environments.

For the file/stream metadata reading, my approach is to parse all files from the playlist before the first streaming process on the serverside. Deefuzzer generates two RSS XML files including the full metadata and optional file link enclosures (podcasting) : the whole playlist and the current playing track. As the "current" one is refreshed between each track playback, it can be used as a pseudo-realtime stream (at the average track time scale..). Also, the whole playlist is in RAM and is then accessible from various internal or external (OSC protocol) functions.

The XML files (could be a JSON stream) can then be parsed on the client side to display things. As an example, I did the whole thing for DeeFuzz radio using rssajax.js:
http://deefuzz.parisson.com/

But, even this is a solid and old school architecture, the parsing is done every 5s on the web pages (with a static file access each time) and is in not so much scalable in my opinion... Your metadata streaming process seems interesting because using socketio which could decrease the workload and provide various cool realtime web functions or effects coming from the server. I'd be interested to see some examples of your experimentations and methods. Maybe we could extend the DeeFuzzer on such things.

Guillaume

@daslicht
Copy link
Author

Thank you for the reply , there is no need to crossfade when using a cue sheet.
A cue sheet is just a text containing something like this:

PERFORMER "BSO, William Steinberg"
TITLE "Also Sprach Zarathustra - Die Planeten"
FILE "Also sprach Zarathustra - Die Planeten.wav" WAVE
  TRACK 01 AUDIO
    TITLE "Also sprach Zarathustra - Einleitung"
    PERFORMER "BSO, William Steinberg"
    INDEX 01 00:00:00
  TRACK 02 AUDIO
    TITLE "Also sprach Zarathustra - Von den Hinterweltlern"
    PERFORMER "BSO, William Steinberg"
    INDEX 01 02:00:28
    ...

syntax: http://digitalx.org/cue-sheet/syntax/

So it's just playing ONE big audio file, but with metadata related to the current playback time
If we could use something like this we wont need to parse the files anymore.

Currently I use this here to parse the icecast stream:
https://github.com/TooTallNate/node-icecast

It has a handler for the metadata change, which looks like this:

function sendSongInfo(){
        if(_socket!==null){
            console.log('SONG ',_parsed);
            _socket.emit('updateSongInfo', _parsed); //very easy with socketIO
        }
    }
...
 res.on('metadata', function (metadata) {
          _parsed = icecast.parse(metadata);
          sendSongInfo();
          console.error('PARSED:',_parsed);
      });

I bet there is something similar to SocketIO available for python either ?
Here is my test : http://78.47.126.11:3001
The stream parsing however isn't 100% stable.

can you get the current playback position of the file in the playlist in DeeFuzz ?
If so we could compare it with the start times in the cue-shet and send teh metadata to the clients on-change.

~Marc

@daslicht
Copy link
Author

Essentially we dont need that cuesheet at all we could also use a json or xml containing the metadata and the start time

@yomguy
Copy link
Owner

yomguy commented Mar 25, 2013

Hi Marc,

Thanks a lot for these examples. I'll look forward to what can be achieve in DeeFuzzer in terms of websocket cool functions.

I'm afraid DeeFuzzer cannot get the track playback time nor seeking in a big audio file...
It is really designed to push / stream series of mp3 or ogg files, even big, without regarding the time scale.

However, the idea is good and I will look further to implement something that can push some metadata to the icecast server reading a cue sheet and relatively to an internal clock timer. So I'll try this module soon:
http://audiotools.sourceforge.net/programming/audiotools_cue.html

I think a good usage would be then to scan any .cue file around the audio with the same filename and parse it if exists.

@daslicht
Copy link
Author

Thak you very much !
On 25.03.2013, at 17:49, Guillaume Pellerin notifications@github.com wrote:

Hi Marc,

Thanks a lot for these examples. I'll look forward to what can be achieve in DeeFuzzer in terms of websocket cool functions.

I'm afraid DeeFuzzer cannot get the track playback time nor seeking in a big audio file...
It is really designed to push / stream series of mp3 or ogg files, even big, without regarding the time scale.

However, the idea is good and I will look further to implement something that can push some metadata to the icecast server reading a cue sheet and relatively to an internal clock timer. So I'll try this module soon:
http://audiotools.sourceforge.net/programming/audiotools_cue.html

I think a good usage would be then to scan any .cue file around the audio with the same filename and parse it if exists.


Reply to this email directly or view it on GitHub.

@daslicht
Copy link
Author

Any news on this?

@yomguy
Copy link
Owner

yomguy commented May 23, 2014

Hi @daslicht!
I'm afraid not, but I'm starting the development again.. So maybe soon ;)

@ChoiZ
Copy link
Contributor

ChoiZ commented May 30, 2014

Great news yomguy 👍

@daslicht
Copy link
Author

👍

@achbed
Copy link
Contributor

achbed commented Jan 24, 2015

I've been using a workaround that involves parsing the file through Audacity, breaking it up into distinct MP3 files (with correct metadata), and loading that up into a folder which Deefuzzer then pushes to the streaming server. This may be an option short-term, but it is more work.

A cue file for metadata would be kind of neat for setting the metadata instead of breaking up the file and would definitely make my life less complicated. Ideally it would be specified as a "source" so we can use the most data from the file. We would have to add detection of CUE vs M3U. We could then use a timer on each station object that is checked against the cue listing every time a packet of data is sent, and updating metadata when needed? That's probably the cleanest thing I can think of.

@daslicht
Copy link
Author

@achbed is the transition between 2 cutted files seamless or do you hear a glitch, click etc ?

@achbed
Copy link
Contributor

achbed commented Jan 24, 2015

It's been seamless for me. I'm running it on a VPS with an SSD-based drive, so your mileage may vary depending on what hardware you throw at it.

@daslicht
Copy link
Author

Hm interesting

@yomguy
Copy link
Owner

yomguy commented Jan 24, 2015

Although we can of course split a mix into separated files, as the transition is seamless on many tested systems here, I agree the internal timer - probably based on datetime.now() - solution is the best.
The only pb is to setup, from another thread, a good time period to checkout the system time and trig the metadata update if it is superior to the time of the track relatively.
Maybe we also have also to impose something like placing the cue file in the same directory than the media and naming it in a good way so that the link can be deduced.
If you don't mind, I rename this isssue from "DeeFuzzer Radio Station" to "Follow metadata in time from CUE or JSON files".

@yomguy yomguy changed the title DeeFuzzer Radio Station Follow metadata in time from CUE or JSON files Jan 24, 2015
@yomguy yomguy added this to the 0.8 milestone Jan 24, 2015
@achbed
Copy link
Contributor

achbed commented Jan 25, 2015

Started tackling this as part of a rewrite of the playlist structure. I've created a new branch (dsw-playlist-object) on my fork to track this. Basically I'm re-implementing the internal playlist of a station to allow for better use of class structures and improve future expandability.

There are two new classes: playlist and track. Playlist contains the list of tracks and all code to maintain the track list (including parsing various playlist file types like M3U and CUE, randomization, next track code, currently playing metadata, etc).

Track contains the media file reference and cached metadata, and can have multiple metadata entries for each track. The metadata is referenced by a timestamp (# of whole seconds) for when the metadata is first valid. This metadata is set either at initialization time (ie, it's from the playlist file), or is read from the media file if there's no metadata set otherwise.

@daslicht
Copy link
Author

Great news !

@daslicht
Copy link
Author

Any news on teh cuesheet or similar to support one source file ?

@yomguy yomguy modified the milestones: 0.8, 0.9 Jan 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants