summaryrefslogtreecommitdiff
path: root/samples/BasicTutorial4.cs
blob: a1d5f594c0bf931dd53f3768b4fe250c85c2e3fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Authors
//   Copyright (C) 2014 Stephan Sundermann <stephansundermann@gmail.com>

using System;
using Gst; 

namespace GstreamerSharp
{
	class Playback
	{
		static Element playbin;
		static bool playing;
		static bool terminate;
		static bool seekEnabled;
		static bool seekDone;
		static long duration;

		public static void Main (string[] args)
		{
			// Initialize Gstreamer
			Application.Init(ref args);

			// Create the elements
			playbin = ElementFactory.Make ("playbin", "playbin");

			if (playbin == null) {
				Console.WriteLine ("Not all elements could be created");
				return;
			}

			// Set the URI to play.
			playbin ["uri"] = "http://download.blender.org/durian/trailer/sintel_trailer-1080p.mp4";

			// Start playing
			var ret = playbin.SetState (State.Playing);
			if (ret == StateChangeReturn.Failure) {
				Console.WriteLine ("Unable to set the pipeline to the playing state.");
				return;
			}

			// Listen to the bus
			var bus = playbin.Bus;
			do {
				var msg = bus.TimedPopFiltered (100 * Constants.MSECOND, MessageType.StateChanged | MessageType.Error |  MessageType.DurationChanged);

				// Parse message
				if (msg != null) {
					HandleMessage (msg);
				}
				else {
					// We got no message, this means the timeout expired
					if (playing) {
						var fmt = Format.Time;
						var current = -1L;

						// Query the current position of the stream
						if (!playbin.QueryPosition (fmt, out current)) {
							Console.WriteLine ("Could not query current position.");
						}

						// if we didn't know it yet, query the stream position
						if (duration <= 0) {
							if (!playbin.QueryDuration (fmt, out duration)) {
								Console.WriteLine ("Could not query current duration.");
							}
						}

						// Print current position and total duration
						Console.WriteLine ("Position {0} / {1}", new TimeSpan (current), new TimeSpan (duration));

						if (seekEnabled && seekDone && current > 10L * Constants.SECOND) {
							Console.WriteLine ("Readed 10s, performing seek...");
							playbin.SeekSimple (fmt, SeekFlags.KeyUnit, 30L * Constants.SECOND);
							seekDone = true;
						}
					}
				}
			} while (!terminate);
		}

		private static void HandleMessage (Message msg) {
			switch (msg.Type) {
			case MessageType.Error:
				string debug;
				GLib.GException exc;
				msg.ParseError (out exc, out debug);
				Console.WriteLine (string.Format ("Error received from element {0}: {1}", msg.Src.Name, exc.Message));
				Console.WriteLine ("Debugging information: {0}", debug);
				terminate = true;
				break;
			case MessageType.Eos:
				Console.WriteLine("End-Of-Stream reached.");
				terminate = true;
				break;
			case MessageType.DurationChanged:
				// The duration has changed, mark the current one as invalid
				duration = -1;
				break;
			case MessageType.StateChanged:
				// We are only interested in state-changed messages from the pipeline
				if (msg.Src == playbin) {
					State oldState, newState, pendingState;
					msg.ParseStateChanged(out oldState, out newState, out pendingState);
					Console.WriteLine ("Pipeline state changed from {0} to {1}:", Element.StateGetName(oldState), Element.StateGetName(newState));

					// Remember wheather we are in the PLAYING state
					playing = newState == State.Playing;

					if (playing) {
						// We have just moved to PLAYING. Check if seeking is possible
						var query = Query.NewSeeking (Format.Time);
						long start, end;
						Format fmt = Format.Time;

						if (playbin.Query (query)) {
							query.ParseSeeking (out fmt, out seekEnabled, out start, out end);

							if (seekEnabled) {
								Console.WriteLine ("Seeking is ENABLED from {0} to {1}", new TimeSpan(start), new TimeSpan(end));
							} else {
								Console.WriteLine ("Seeking DISABLED for this stream.");
							}
						} else {
							Console.WriteLine ("Seeking query failed.");
						}
					}
				}
				break;
			default:
				// We should not reach here
				Console.WriteLine ("Unexpected message received.");
				break;
			} 
		}
	}
}