diff --git a/src/playbin.vala b/src/playbin.vala index 94f5b16..e0c7ce4 100644 --- a/src/playbin.vala +++ b/src/playbin.vala @@ -4,16 +4,6 @@ enum PlaybinState { PLAYING, } -errordomain PlaybinError { - MPV, -} - -private void check_mpv_error (int ec) throws PlaybinError { - if (ec < 0) { - throw new PlaybinError.MPV ("%s", Mpv.error_string (ec)); - } -} - private class SourceFuncWrapper { public SourceFunc inner; @@ -32,7 +22,7 @@ class Playbin : GLib.Object { get { return _volume; } set { _volume = value; - mpv_set_property_int64.begin ("volume", value); + assert (mpv.set_property_int64 ("volume", value) >= 0); } } @@ -41,7 +31,7 @@ class Playbin : GLib.Object { get { return _mute; } set { _mute = value; - mpv_set_property_flag.begin ("mute", value); + assert (mpv.set_property_flag ("mute", value) >= 0); } } @@ -65,87 +55,29 @@ class Playbin : GLib.Object { } private void on_play_queue_items_changed (ListModel play_queue, uint position, uint removed, uint added) { - // FIXME: these should prolly be chained - - for (uint i = 0; i < removed; i += 1) { - this.mpv_command.begin ({"playlist-remove", position.to_string ()}); - } - - for (uint i = 0; i < added; i += 1) { - this.mpv_command.begin ({"loadfile", this.api.stream_uri (((Subsonic.Song) play_queue.get_item (position+i)).id), "insert-at-play", (position+i).to_string ()}); - } - } - - private SourceFuncWrapper[] mpv_command_callbacks = {}; - private int[] mpv_command_error = {}; - - private async void mpv_command (string[] args) throws Error { - int userdata = -1; - for (int i = 0; i < this.mpv_command_callbacks.length; i += 1) { - if (this.mpv_command_callbacks[i].inner == null) { - userdata = i; - break; + try { + for (uint i = 0; i < removed; i += 1) { + assert (this.mpv.command ({"playlist-remove", position.to_string ()}) >= 0); } - } - if (userdata == -1) { - userdata = this.mpv_command_callbacks.length; - this.mpv_command_callbacks += new SourceFuncWrapper (); - this.mpv_command_error += 0; - } - check_mpv_error (this.mpv.command_async ((uint64) userdata, args)); - this.mpv_command_callbacks[userdata].inner = this.mpv_command.callback; - yield; - - check_mpv_error (this.mpv_command_error[userdata]); - } - - private SourceFuncWrapper[] mpv_set_property_callbacks = {}; - private int[] mpv_set_property_error = {}; - - private async void mpv_set_property (string name, Mpv.Format format, void *data) throws Error { - int userdata = -1; - for (int i = 0; i < this.mpv_set_property_callbacks.length; i += 1) { - if (this.mpv_set_property_callbacks[i].inner == null) { - userdata = i; - break; + for (uint i = 0; i < added; i += 1) { + assert (this.mpv.command ({"loadfile", this.api.stream_uri (((Subsonic.Song) play_queue.get_item (position+i)).id), "insert-at-play", (position+i).to_string ()}) >= 0); } + } catch (Error e) { + error ("could not update mpv playlist: %s\n", e.message); } - if (userdata == -1) { - userdata = this.mpv_set_property_callbacks.length; - this.mpv_set_property_callbacks += new SourceFuncWrapper (); - this.mpv_set_property_error += 0; - } - - check_mpv_error (this.mpv.set_property_async ((uint64) userdata, name, format, data)); - this.mpv_set_property_callbacks[userdata].inner = this.mpv_set_property.callback; - yield; - - check_mpv_error (this.mpv_set_property_error[userdata]); - } - - private async void mpv_set_property_int64 (string name, int64 value) throws Error { - yield this.mpv_set_property (name, Mpv.Format.INT64, &value); - } - - private async void mpv_set_property_flag (string name, bool value) throws Error { - int flag = value ? 1 : 0; - yield this.mpv_set_property (name, Mpv.Format.FLAG, &flag); } public Playbin () { - try { - check_mpv_error (this.mpv.initialize ()); - check_mpv_error (this.mpv.set_property_string ("user-agent", Audrey.Const.user_agent)); - check_mpv_error (this.mpv.set_property_string ("video", "no")); - check_mpv_error (this.mpv.set_property_string ("prefetch-playlist", "yes")); - check_mpv_error (this.mpv.set_property_string ("gapless-audio", "yes")); - check_mpv_error (this.mpv.observe_property (0, "time-pos", Mpv.Format.DOUBLE)); - check_mpv_error (this.mpv.observe_property (1, "duration", Mpv.Format.DOUBLE)); - check_mpv_error (this.mpv.observe_property (2, "playlist-pos", Mpv.Format.INT64)); - } catch (Error e) { - error ("could not initialize mpv: %s", e.message); - } + assert (this.mpv.initialize () >= 0); + assert (this.mpv.set_property_string ("user-agent", Audrey.Const.user_agent) >= 0); + assert (this.mpv.set_property_string ("video", "no") >= 0); + assert (this.mpv.set_property_string ("prefetch-playlist", "yes") >= 0); + assert (this.mpv.set_property_string ("gapless-audio", "yes") >= 0); + assert (this.mpv.observe_property (0, "time-pos", Mpv.Format.DOUBLE) >= 0); + assert (this.mpv.observe_property (1, "duration", Mpv.Format.DOUBLE) >= 0); + assert (this.mpv.observe_property (2, "playlist-pos", Mpv.Format.INT64) >= 0); + this.mpv.wakeup_callback = () => { Idle.add (() => { @@ -154,18 +86,6 @@ class Playbin : GLib.Object { if (event.event_id == Mpv.EventId.NONE) break; switch (event.event_id) { - case Mpv.EventId.COMMAND_REPLY: - this.mpv_command_error[event.reply_userdata] = event.error; - var cb = (owned) this.mpv_command_callbacks[event.reply_userdata].inner; - cb (); - break; - - case Mpv.EventId.SET_PROPERTY_REPLY: - this.mpv_set_property_error[event.reply_userdata] = event.error; - var cb = (owned) this.mpv_set_property_callbacks[event.reply_userdata].inner; - cb (); - break; - case Mpv.EventId.PROPERTY_CHANGE: switch (event.reply_userdata) { case 0: @@ -248,38 +168,38 @@ class Playbin : GLib.Object { public void seek (double position) { this.position = position; - this.mpv_command.begin ({"seek", position.to_string (), "absolute"}); + assert (this.mpv.command ({"seek", position.to_string (), "absolute"}) >= 0); } // manually changes which track in the play queue to play public void select_track (uint position) requires (position < this.play_queue.get_n_items ()) { - this.mpv_command.begin ({"playlist-play-index", position.to_string ()}); + assert (this.mpv.command ({"playlist-play-index", position.to_string ()}) >= 0); this.state = PlaybinState.PLAYING; } public void pause () { assert (this.state != PlaybinState.STOPPED); this.state = PlaybinState.PAUSED; - this.mpv_command.begin ({"pause"}); + assert (this.mpv.command ({"pause"}) >= 0); } public void play () { assert (this.state != PlaybinState.STOPPED); this.state = PlaybinState.PLAYING; - this.mpv_command.begin ({"play"}); + assert (this.mpv.command ({"play"}) >= 0); } public void next_track () { assert (this.state != PlaybinState.STOPPED); this.state = PlaybinState.PLAYING; - this.mpv_command.begin ({"playlist-next-playlist"}); + assert (this.mpv.command ({"playlist-next-playlist"}) >= 0); } public void prev_track () { assert (this.state != PlaybinState.STOPPED); this.state = PlaybinState.PLAYING; - this.mpv_command.begin ({"playlist-prev-playlist"}); + assert (this.mpv.command ({"playlist-prev-playlist"}) >= 0); } } diff --git a/src/vapi/mpv.vapi b/src/vapi/mpv.vapi index c7bbe8c..1c9bfa4 100644 --- a/src/vapi/mpv.vapi +++ b/src/vapi/mpv.vapi @@ -1,8 +1,33 @@ [CCode (cheader_filename = "mpv/client.h")] namespace Mpv { - [CCode (cname = "mpv_error_string")] - public unowned string error_string (int error); + [CCode (cname = "mpv_error", cprefix = "MPV_ERROR_", has_type_id = false)] + public enum Error { + SUCCESS, + EVENT_QUEUE_FULL, + NOMEM, + UNINITIALIZED, + INVALID_PARAMETER, + OPTION_NOT_FOUND, + OPTION_FORMAT, + OPTION_ERROR, + PROPERTY_NOT_FOUND, + PROPERTY_FORMAT, + PROPERTY_UNAVAILABLE, + PROPERTY_ERROR, + COMMAND, + LOADING_FAILED, + AO_INIT_FAILED, + VO_INIT_FAILED, + NOTHING_TO_PLAY, + UNKNOWN_FORMAT, + UNSUPPORTED, + NOT_IMPLEMENTED, + GENERIC; + + [CCode (cname = "mpv_error_string")] + public unowned string to_string (); + } public delegate void WakeupCallback (); @@ -13,7 +38,7 @@ namespace Mpv { public Handle (); [CCode (cname = "mpv_initialize")] - public int initialize (); + public Error initialize (); [CCode (cname = "mpv_wait_event")] public unowned Event *wait_event (double timeout); @@ -22,20 +47,28 @@ namespace Mpv { [CCode (cname = "mpv_set_wakeup_callback")] set; } + [CCode (cname = "mpv_set_property")] + public Error set_property (string name, Format format, void *data); + [CCode (cname = "mpv_set_property_string")] - public int set_property_string (string name, string data); + public Error set_property_string (string name, string value); - [CCode (cname = "mpv_set_property_async")] - public int set_property_async (uint64 reply_userdata, string name, Format format, void *data); + public Error set_property_int64 (string name, int64 value) { + return this.set_property (name, Format.INT64, &value); + } - [CCode (cname = "mpv_command_async")] - public int command_async ( - uint64 reply_userdata, + public Error set_property_flag (string name, bool value) { + int flag = value ? 1 : 0; + return this.set_property (name, Format.INT64, &flag); + } + + [CCode (cname = "mpv_command")] + public Error command ( [CCode (array_length = false)] string[] args); [CCode (cname = "mpv_observe_property")] - public int observe_property (uint64 reply_userdata, string name, Format format); + public Error observe_property (uint64 reply_userdata, string name, Format format); } [CCode (cname = "mpv_format", cprefix = "MPV_FORMAT_", has_type_id = false)] @@ -80,7 +113,7 @@ namespace Mpv { [CCode (cname = "mpv_event")] public struct Event { EventId event_id; - int error; + Error error; uint64 reply_userdata; void *data; } @@ -98,4 +131,3 @@ namespace Mpv { } } -