TIME_FORMAT
Description:
A string that can be used in printf-like format strings to display a ClockTime value in `h:m:s` format.
Use TIME_ARGS to construct the matching arguments.
Example:
``` C printf("%" GST_TIME_FORMAT "\n", GST_TIME_ARGS(ts)); ```
Example: Time management:
// See http://docs.gstreamer.com/x/cAAF
// for a detailed description
public class Main {
	// TODO: GST_CLOCK_TIME_IS_VALID(time) isn't bound (Tue Aug 20, 2013)
	private static inline bool GST_CLOCK_TIME_IS_VALID (Gst.ClockTime time) {
		return ((time) != Gst.CLOCK_TIME_NONE);
	}
	// Our one and only element
	private Gst.Element playbin2;
	// Are we in the PLAYING state?
	private bool playing;
	// Should we terminate execution?
	private bool terminate;
	// Is seeking enabled for this media?
	private bool seek_enabled;
	// Have we performed the seek already?
	private bool seek_done;
	// How long does this media last, in nanoseconds
	private Gst.ClockTime duration;
	// Forward definition of the message processing function
	private void handle_message (Gst.Message msg) {
		switch (msg.type) {
		case Gst.MessageType.ERROR:
			GLib.Error err;
			string debug_info;
			msg.parse_error (out err, out debug_info);
			print ("Error received from element %s: %s\n", msg.src.name, err.message);
			print ("Debugging information: %s\n", (debug_info != null)? debug_info : "none");
			this.terminate = true;
			break;
		case Gst.MessageType.EOS:
			print ("End-Of-Stream reached.\n");
			this.terminate = true;
			break;
		case Gst.MessageType.DURATION_CHANGED :
			// The duration has changed, mark the current one as invalid:
			this.duration = Gst.CLOCK_TIME_NONE;
			break;
		case Gst.MessageType.STATE_CHANGED:
			Gst.State old_state;
			Gst.State new_state;
			Gst.State pending_state;
			msg.parse_state_changed (out old_state, out new_state, out pending_state);
			if (msg.src == this.playbin2) {
				print ("Pipeline state changed from %s to %s:\n",
					Gst.Element.state_get_name (old_state),
					Gst.Element.state_get_name (new_state));
				// Remember whether we are in the PLAYING state or not:
				this.playing = (new_state == Gst.State.PLAYING);
				if (this.playing) {
					// We just moved to PLAYING. Check if seeking is possible:
					Gst.Query query = new Gst.Query.seeking (Gst.Format.TIME);
					int64 start;
					int64 end;
					if (this.playbin2.query (query)) {
						query.parse_seeking (null, out this.seek_enabled, out start, out end);
						if (this.seek_enabled) {
							// GST_TIME_ARGS isn't available (Tue Aug 20, 2013)
							//print ("Seeking is ENABLED from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT "\n",
							//		GST_TIME_ARGS (start), GST_TIME_ARGS (end));
							print ("Seeking is ENABLED from %" + int64.FORMAT + " to %" + int64.FORMAT + "\n", start, end);
						} else {
							print ("Seeking is DISABLED for this stream.\n");
						}
					} else {
						print ("Seeking query failed.\n");
					}
				}
			}
			break;
		default:
			// We should not reach here:
			assert_not_reached ();
		}
	}
	public int run () {
		// init:
		this.playing = false;
		this.terminate = false;
		this.seek_enabled = false;
		this.seek_done = false;
		this.duration = Gst.CLOCK_TIME_NONE;
		// Create the elements:
		this.playbin2 = Gst.ElementFactory.make ("playbin", "playbin");
		if (this.playbin2 == null) {
			print ("Not all elements could be created.\n");
			return -1;
		}
		// Set the URI to play:
		this.playbin2.set ("uri", "http://docs.gstreamer.com/media/sintel_trailer-480p.webm");
		// Start playing:
		Gst.StateChangeReturn ret = this.playbin2.set_state (Gst.State.PLAYING);
		if (ret == Gst.StateChangeReturn.FAILURE) {
			stderr.puts ("Unable to set the pipeline to the playing state.\n");
			this.playbin2 = null;
			return -1;
		}
		// Listen to the bus:
		Gst.Bus bus = this.playbin2.get_bus ();
		do {
			Gst.Message msg = bus.timed_pop_filtered (100 * Gst.MSECOND,
				Gst.MessageType.STATE_CHANGED | Gst.MessageType.ERROR | Gst.MessageType.EOS | Gst.MessageType.DURATION_CHANGED);
			// Parse message:
			if (msg != null) {
				handle_message (msg);
			} else {
				// We got no message, this means the timeout expired:
				if (this.playing) {
					Gst.Format fmt = Gst.Format.TIME;
					int64 current = -1;
					// Query the current position of the stream:
					if (!this.playbin2.query_position (fmt, out current)) {
						stderr.puts ("Could not query current position.\n");
					}
					// If we didn't know it yet, query the stream duration:
					if (!GST_CLOCK_TIME_IS_VALID (this.duration)) {
						if (!this.playbin2.query_duration (fmt, out this.duration)) {
							stderr.puts ("Could not query current duration.\n");
						}
					}
					// Print current position and total duration:
					// GST_TIME_ARGS isn't available (Tue Aug 20, 2013)
					// print ("Position %" + Gst.TIME_FORMAT + " / %" + Gst.TIME_FORMAT + "\r",
					//  GST_TIME_ARGS (current), GST_TIME_ARGS (this.duration));
					print ("Position %" + int64.FORMAT + " / %" + int64.FORMAT + "\r",
						current, this.duration);
					// If seeking is enabled, we have not done it yet, and the time is right, seek:
					if (this.seek_enabled && !this.seek_done && current > 10 * Gst.SECOND) {
						print ("\nReached 10s, performing seek...\n");
						this.playbin2.seek_simple (Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, 30 * Gst.SECOND);
						this.seek_done = true;
					}
				}
			}
		} while (!this.terminate);
		// Free resources:
		this.playbin2.set_state (Gst.State.NULL);
		this.playbin2 = null;
		return 0;
	}
	public static int main (string[] args) {
		// Initialize GStreamer:
		Gst.init (ref args);
		return new Main ().run ();
	}
}valac --pkg gstreamer-1.0 --enable-experimental time-management.valaNamespace: Gst
  
  Package: gstreamer-1.0