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;
}
}