How to play sound using Gtk

I am completely new to Gtk development, and I am struggling to find a way to play sound using gtk.

From the documentation, it seems there is a MediaFile class that inherits a MediaStream class that can play files, although I am not sure whether this suits Audio files.

        const mediaFile = Gtk.MediaFile.new_for_resource("/dev/louscouture/watchsync/beep.wav")
        mediaFile.play()

It doesn’t say to me that the function doesn’t exists but the sound does not play. I have no idea how to do this.

You want to use libgsound!

You most definitely don’t want to use an unmaintained wrapper like gsound around an unmaintained library like libcanberra.

Playing a sound is done by loading a file using GtkMediaFile, and using the GtkMediaStream API:

You may need to set the volume of the media stream to 1.

There is a simple example in the GTK repository: tests/testsounds.c · main · GNOME / gtk · GitLab

3 Likes

There is an “Audio” demo in Workbench library in case that’s helpful.

I am unable to reproduce this for my use case, which is a sounds that needs to play without a MediaControlWidget

        const file = Gio.File.new_for_uri("/beep.ogg");

        let media_stream = Gtk.MediaFile.new_for_file(file)
        media_stream.set_volume(1.0)
        media_stream.play()

/beep.ogg is an absolute path (which is probably not what you intended), and also is not a URI.

This API seems to fail silently when the file is missing. You can connect to notify::prepared on the Gtk.MediaStream and then check the has-audio property.

The example in Workbench still works for me after modifying it not to use Gtk.MediaControls.

can you show your example ?

I did use a ressource and I listened to notify::change event and the sounds is there but it is not playing

 let media_stream = Gtk.MediaFile.new_for_resource("/dev/louscouture/watchsync/beep.wav")

media_stream.connect("notify::prepared", ()=>{console.log(media_stream.has_audio);media_stream.set_volume(1.0);media_stream.play()})

In Workbench, you can just not set controls.media_stream, and it’ll be inactive. Simplifying it all the way to this also works.

import Gio from "gi://Gio";
import Gtk from "gi://Gtk";

let file = Gio.File.new_for_uri(workbench.resolve("./Dog.ogg"));
let media_stream = Gtk.MediaFile.new_for_file(file);
media_stream.play();

I did notice at one point that it wouldn’t play the first time (even with the original, unmodified example). I haven’t been able to make that happen again though.

Is there a way to do this but on gnome builder.
I want it to be on a real app.

The template uses workbench specific class.

I cannot use this to make a real app using builder.

It is unclear looking at the code workbench.resolve

I’ve tried using ressource but the sound just doesn’t play

Probably because your resource isn’t registered properly.

You’ll have to share a repo for us to be able to help you.

I ended up finding the reason why the sound wasn’t playing

I had to register permissions in the finish args in my .json file

        "--socket=pulseaudio",

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.