Playing audio files from Julia

What would be the recommended way to (just) play a MP3 file from Julia?
Most related posts was Audio processing in Julia
but I wonder if there is anything new, and also if you would know of some cross-platform binaries that I could wrap around

2 Likes

I don’t know about the recommended way, but an easy one would be to use ffplay. We have a JLL for it, so you can do:

using FFplay_jll
path = "sample.mp3"
ffplay() do exe
    run(`$exe $path`)
end

Sound was not working for me (on Linux), because ALSA was not being discovered (it was looking for it at /workspace/destdir/, so there might be something wrong with the build). I had to change run(`$exe $path`) to

run(addenv(`$exe $path`, "ALSA_CONFIG_PATH" => "/usr/share/alsa/alsa.conf", 
                         "ALSA_PLUGIN_DIR" => "/usr/lib/alsa-lib/"))

You might want to pass -nodisp to hide the player interface, or -loglevel fatal to turn off logs.

4 Likes

That worked great. I also had the same ALSA issue and your solution worked perfectly!

I think the issue with ALSA might be fixed by adjusting the build script for alsa_jll. I submitted an issue: `alsa`: set `configdir` and `plugindir`? · Issue #8073 · JuliaPackaging/Yggdrasil · GitHub

1 Like

Thanks, I don’t know who marked your answer as a solution, but this only works on Linux (maybe FreeBSD, doubt macOS) but not Windows, so I unchecked.

Obviously Julia doesn’t need audio-playback for itself… but if not in Base (Python has I believe audio playback), then at least a go-to library for cross-platform. And it could and should be documented in Julia’s docs. This library may already exist, I just haven’t checked (yet), and that should be pointed to here.

EDIT: @barucden Sorry, I assuemd, I just saw “ALSA” i.e. Linux-specific, but I checked and actually Windows is supported, seemingly all platforms including macOS x86_64 (x86_64-apple-darwin) so only unclear about M1 macs.

Anyway, the workaround should likely not interfere with platforms it’s not intended at, but neither should it be needed on Linux. It should work out of the box. So add a PR there (rather than Linux users to their code)?

It’s great if we have cross-platform audio working. ffmpeg is cross-platform. Good enough for most, though a bit heavy dependency. FFplay_jll maybe smaller, but do we have something simple/small for e.g. WAV or more liglty compressed formats? Also is this async or sync playing or both available, and many concurrent etc.? [Even some effects, Doppler, surround etc.? Just curious, we at least have the most needed basics it seems.]

Do you know why it does not work on Windows? ffplay should be available on Windows too.

1 Like

Isn’t ffmpeg also working on Windows and MacOS?

I agree. I submitted an issue to Yggdrasil along with an idea on how to resolve it. Now, I don’t know if that solution is good or not. I don’t know enough about ALSA and its build process or about julia’s Binary Builder. Hopefully, someone more knowledgeable than me steps up and joins in.

1 Like

I’m not sure about .mp3 formats specifically, but wanted to leave a quick comment that there is PortAudio.jl, which seems to use libportaudio_jll GitHub - JuliaBinaryWrappers/libportaudio_jll.jl

1 Like

Thanks,

Historically simply playing any audio (and/or MP3) was a mess on Linux. I think ALSA was the solution, and likely is available on all non-ancient Linux. I would have thought in same directory too…

I do have /usr/share/alsa/alsa.conf though not /usr/lib/alsa-lib but at least in my (default install) Mint (Ubuntu sort of) I could play without the workaround.

I DID manage to install FFplay_jll but not play audo, with or without the workaround doubt I misapplied it, or the 360 byte auto audio broken, not yet tested elsewhere):

I did expect no text output, as opposed to a lot:

ffplay version 4.3.1 Copyright (c) 2003-2020 the FFmpeg developers
  built with gcc 8.1.0 (GCC)
[..]
  WARNING: library configuration mismatch
  avutil      configuration: --enable-cross-compile --cross-prefix=/opt/x86_64-linux-gnu/bin/x86_64-linux-gnu- --arch=x86_64 --target-os=linux --cc=cc --cxx=c++ --dep-cc=cc --ar=ar --nm=nm --objcc=objc --sysinclude=/workspace/destdir/include --pkg-config=/usr/bin/pkg-config --pkg-config-flags=--static --prefix=/workspace/destdir --sysroot=/opt/x86_64-linux-gnu/x86_64-linux-gnu/sys-root --extra-libs=-lpthread --enable-gpl --enable-version3 --enable-nonfree --disable-static --enable-shared --enable-pic --disable-debug --disable-doc --enable-avresample --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libx264 --enable-libx265 --enable-libvpx --enable-encoders --enable-decoders --enable-muxers --enable-demuxers --enable-parsers --enable-openssl --disable-schannel --extra-cflags=-I/workspace/destdir/include --extra-ldflags=-L/workspace/destdir/lib --enable-nvenc --enable-cuda-llvm

[..]
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
[mp3 @ 0x7efd3c000bc0] Format mp3 detected only with low score of 25, misdetection possible!
[mp3 @ 0x7efd3c000bc0] Estimating duration from bitrate, this may be inaccurate
Input #0, mp3, from '/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/test/support/fixtures/test.mp3':
  Duration: 00:00:00.36, start: 0.000000, bitrate: 8 kb/s
[..]

FYI: BlueZ is Bluetooth dependency on Linux say maybe understandable dependency (for audio), while e.g. Fontconfig isn’t…

I got (self-inflicted(?), as usual, I know workaround) 8 screenfuls!! of:

ERROR: Unsatisfiable requirements detected for package OpenSSL_jll [458c3c95]:
 OpenSSL_jll [458c3c95] log:
 ├─possible versions are: 1.1.1-3.0.13 or uninstalled
 ├─restricted by compatibility requirements with FFMPEG_jll [b22a6f82] to versions: [1.1.10-1.1.23, 3.0.9-3.0.13]
 │ └─FFMPEG_jll [b22a6f82] log:
[..]

so:
$ julia --project=.

   Installed libass_jll ───── v0.14.0+4
   Installed FFMPEG_jll ───── v4.3.1+4
   Installed Fontconfig_jll ─ v2.13.1+14
   Installed x265_jll ─────── v3.0.0+3
   Installed Bzip2_jll ────── v1.0.6+5
   Installed LibVPX_jll ───── v1.10.0+0
   Installed libfdk_aac_jll ─ v0.1.6+4
   Installed FreeType2_jll ── v2.10.1+5
   Installed x264_jll ─────── v2020.7.14+2
   Installed FFplay_jll ───── v4.3.1+0
   Installed Elfutils_jll ─── v0.179.0+0
  Downloaded artifact: x265
  Downloaded artifact: libfdk_aac
  Downloaded artifact: libass
  Downloaded artifact: OpenCV
  Downloaded artifact: FFMPEG
  Downloaded artifact: Bzip2
  Downloaded artifact: LibVPX
  Downloaded artifact: Elfutils
  Downloaded artifact: Fontconfig
  Downloaded artifact: x264
  Downloaded artifact: FreeType2
  Downloaded artifact: FFplay
    Updating `~/Project.toml`
⌃ [c4dce911] + FFplay_jll v4.3.1+0
    Updating `~/Manifest.toml`
  [692b3bcd] ↑ JLLWrappers v1.4.1 ⇒ v1.5.0
  [1914dd2f] ↑ MacroTools v0.5.10 ⇒ v0.5.13
  [21216c6a] ↑ Preferences v1.3.0 ⇒ v1.4.1
  [cd00e070] + BerkeleyDB_jll v18.1.40+0
  [471b5b61] + BlueZ_jll v5.54.0+1
⌅ [6e34b625] ↓ Bzip2_jll v1.0.8+0 ⇒ v1.0.6+5
[..]
⌃ [a3f928ae] ↓ Fontconfig_jll v2.13.93+0 ⇒ v2.13.1+14
⌃ [d7e528f0] ↓ FreeType2_jll v2.10.4+0 ⇒ v2.10.1+5
[..]

[Annoyingly, some (Youtube) audio (is likely mono, and thus) only plays in left ear… You might think no producer makes such mistake, this might not be a problem on Windows or macOS, anyone know not just how do (automatically) center or play such equally in both ears, with FFplay, but globally if possible, i.e. fixing all web browsers/YouTube…?]

It does, and it supports e.g. macOS aarch64 (aarch64-apple-darwin) (unlike other package, not sure if it still works there), i.e. all platforms, even Linux i686 {libc=musl} (i686-linux-musl) and x86_64-unknown-freebsd.jl.

For what it’s worth, I did get PortAudio play audio, and libportaudio_jll seems to be a very simple dependency, depending on alsa_jll, though none of this handles MP3(?), at least without something more. You can do (maybe it’s to make it work with):

add https://github.com/JuliaAudio/MP3.jl

I tried the last example in the docs (I DID get audio, though only in left ear, likely not a bug", though non-optimal default…) starting with:

using PortAudio, SampledSignals
[..]

worked while getting, non-ideal...:

Linux i686 {libc=musl} (i686-linux-musl)ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
┌ Warning: libportaudio: Output underflowed
└ @ PortAudio ~/.julia/packages/PortAudio/HNBv4/src/PortAudio.jl:99
[..]

PortAudio is also a rather small, but not as small dependency:

pkg> add PortAudio
   Resolving package versions...
   Installed EllipsisNotation ─ v1.6.0
   Installed FFTW ───────────── v1.8.0
   Installed Static ─────────── v0.8.9
   Installed SampledSignals ─── v2.1.3
   Installed IntervalSets ───── v0.5.4
   Installed PortAudio ──────── v1.3.0
    Updating `~/Project.toml`
  [80ea8bcb] + PortAudio v1.3.0
    Updating `~/Manifest.toml`
  [621f4979] + AbstractFFTs v1.5.0
⌅ [4fba245c] + ArrayInterface v6.0.25
  [30b0a656] + ArrayInterfaceCore v0.1.29
⌅ [34da2185] + Compat v3.47.0
  [187b0558] + ConstructionBase v1.5.4
  [717857b8] + DSP v0.7.9
  [8bb1440f] + DelimitedFiles v1.9.1
  [ffbed154] + DocStringExtensions v0.9.3
⌃ [da5c29d0] + EllipsisNotation v1.6.0
  [7a1cc6ca] + FFTW v1.8.0
  [53c48c17] + FixedPointNumbers v0.8.4
  [615f187c] + IfElse v0.1.1
⌅ [8197267c] + IntervalSets v0.5.4
[..]

There’s

ffplay -v 0 -autoexit -nodisp file

for a “quiet” run.

2 Likes

Thanks, that finally worked (quiet for the text, non-quiet for audio, still about 3x slower than the audio itself (unless it has a lot of silence after, as part of the file), the other audio file I was trying was seemingly problematic/too short):

shell> time /var/lib/flatpak/runtime/org.freedesktop.Platform/x86_64/21.08/c7252386179c4c1ecf5d93bdaec6ca82852dddfdae7112b5c3177f7424c4a928/files/bin/ffplay -v 0 -autoexit -nodisp /usr/share/code/resources/app/out/vs/platform/audioCues/browser/media/chatRequestSent.mp3


real	0m1,736s

The code with that line also works now (sort of), but opens a GUI window, though empty one…, and doesn’t terminate (same with ALSA workaround), until with more added, and I tried with async, works, with small delay, so not very precise to be useful (would need a way to play MP3 without invoking processes):

@time (@async ffplay() do exe
           run(`$exe -v 0 -autoexit -nodisp $path`) # run(addenv(`$exe $path`, "ALSA_CONFIG_PATH" => "/usr/share/alsa/alsa.conf", 
           #                     "ALSA_PLUGIN_DIR" => "/usr/lib/alsa-lib/")) # run(`$exe $path`)
       end;
       @async ffplay() do exe
           run(`$exe -v 0 -autoexit -nodisp $path`)
       end;)

0.000139 seconds (78 allocations: 6.953 KiB)

On Windows, the mp3 file plays in the background and the only way to stop it is to find ffplay.exe in the Task Manager and kill it.

1 Like