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