I recently found the bpmdetect element in GStreamer, and thought it would be neat to try it out and see how well it works. The GStreamer bpmdetect plugin is mostly undocumented, so I had to dig in the source code to figure out how to extract tags from it. The operation is pretty simple:
- Setup a pipeline to read in a file, put a fakesink at the end of the pipeline and set ‘sync’ to false
- Insert the bpmdetect element
- However, due to this bug, insert a capsfilter before the element to mix it down to a single channel!
- Attach a message handler, and listen for taglist messages
- If you already have the BPM tag on the file, then it will be emitted by whatever is decoding the audio too. So, what I do is look for messages that *only* have the beats-per-minute tag in the tag list
- The bpm is accumulated, so the last BPM message you get will be the calculated rate
Pretty simple! Of course, the results are only as reliable as libsoundtouch’s BPM detection is… but it seems to be correct at least some of the time. Expect to see this code in Exaile soon as a companion to the manual BPM counter! 🙂
Code is available in a gist on github: https://gist.github.com/virtuald/c30032a5b8cdacd1a6c0