Archive / / / / / Echo.Playback.PlaybackService.vala
2008-12-02 06:05:13 UTC
previous next
/* vim: set noexpandtab tabstop=4 shiftwidth=4 nowrap textwidth=100 * * Echo Media Player * Copyright (C) 2008 Shane O'Connell * * [ The original file includes a copyright header in this location describing * the file as being released under the terms of the GNU General Public * License. It has been removed in order to display the file as part of the * archive. ] */ using Echo.Interfaces; public class Echo.Playback.PlaybackService : GLib.Object { // ----------- Signals ----------- public signal void state_changed(); public signal void track_changed(bool is_automatic); // ----------- Private fields ----------- private Gst.Pipeline _gst_player; private PlaybackState _current_state = PlaybackState.STOPPED; private ITrack _track = null; private ShuffleType _shuffle_type = ShuffleType.NONE; // ----------- Public attributes ----------- public PlaybackState current_state { get { return _current_state; } } public weak ITrack? current_track { get { if (_track == null) return null; else return _track; } } /* public IPlaySource? current_source { get { if (_track == null) return null; else { var source = _track.get_source(); return source; } } } public int current_index { get { if (_track == null) return -1; else return _track.get_index(); } }*/ // ----------- Methods ----------- public PlaybackService(ref weak string[] args) { Gst.init(ref args); _gst_player = (Gst.Pipeline)Gst.ElementFactory.make("playbin", "player"); var bus = _gst_player.get_bus(); bus.add_watch(bus_callback); } private bool bus_callback(Gst.Bus bus, Gst.Message message) { switch(message.type) { case Gst.MessageType.ERROR: GLib.Error gerror; string debug_string; message.parse_error(out gerror, out debug_string); stderr.printf("GStreamer error: %s\nGStreamer debug information:\n%s\n\n", gerror.message, debug_string); break; case Gst.MessageType.EOS: next(true); break; } return true; } private void change_track(ITrack? track, bool is_automatic) { if (_track != null) _track.track_invalidated -= this.on_track_invalidated; if (track == null || !track.valid) { _gst_player.set_state(Gst.State.READY); if (_current_state != PlaybackState.STOPPED) { _current_state = PlaybackState.STOPPED; state_changed(); } if (_track != null && _track.valid) { _track = null; track_changed(is_automatic); } _track = null; } else { _track = track; _track.track_invalidated += this.on_track_invalidated; _gst_player.set_state(Gst.State.READY); ((GLib.Object)_gst_player).set("uri", _track.uri); _gst_player.set_state(Gst.State.PLAYING); if (_current_state != PlaybackState.PLAYING) { _current_state = PlaybackState.PLAYING; state_changed(); } track_changed(is_automatic); } } public void play(ITrack track) { change_track(track, false); } public void stop() { change_track(null, false); } public void next(bool is_automatic = false) { ITrack next_track; if (_shuffle_type != ShuffleType.NONE) next_track = _track.source.get_track( GLib.Random.int_range(0, _track.source.get_num_tracks())); else next_track = _track.get_next(); change_track(next_track, is_automatic); } public void prev() { change_track(_track.get_prev(), false); } public void pause() { if (_current_state == PlaybackState.PLAYING || _current_state == PlaybackState.BUFFERING) { _gst_player.set_state(Gst.State.PAUSED); if (_current_state != PlaybackState.PAUSED) { _current_state = PlaybackState.PAUSED; state_changed(); } } } public void unpause() { if (_current_state == PlaybackState.PAUSED && _track != null && _track.valid) { _gst_player.set_state(Gst.State.PLAYING); _current_state = PlaybackState.PLAYING; state_changed(); } } private void on_track_invalidated(ITrack track) { if (track == _track) stop(); } public void set_shuffle(ShuffleType shuffle_type) { _shuffle_type = shuffle_type; } public int64 get_track_length() { Gst.Format format = Gst.Format.TIME; int64 length; if (_gst_player.query_duration(ref format, out length) && format == Gst.Format.TIME) return (length / 1000000); // return in ms else return -1; } public int64 get_track_position() { Gst.Format format = Gst.Format.TIME; int64 position; if (_gst_player.query_position(ref format, out position) && format == Gst.Format.TIME) return (position / 1000000); // return in ms else return -1; } }