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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
// Authors
// Copyright (C) 2014 Stephan Sundermann <stephansundermann@gmail.com>
using System;
using Gst;
using System.Runtime.InteropServices;
namespace GstreamerSharp
{
class Playback
{
// playbin flags
static uint Video = (1 << 0); // We want video output
static uint Audio = (1 << 1); // We want audio output
static uint Text = (1 << 2); // We want subtitle output
static Element Playbin;
static int NAudio, NVideo, NText;
static int CurrentVideo, CurrentAudio, CurrentText;
static GLib.MainLoop MainLoop;
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://docs.gstreamer.com/media/sintel_trailer-480p.ogv";
// Set the subtitle URI to play and some font description
Playbin ["suburi"] = "http://docs.gstreamer.com/media/sintel_trailer_gr.srt";
Playbin ["subtitle-font-desc"] = "Sans, 18";
// Set flags to show Audio and Video and Subtitles
var flags = (uint)Playbin ["flags"];
flags |= Audio | Video | Text;
Playbin ["flags"] = flags;
// Add a bus watch, so we get notified when a message arrives
var bus = Playbin.Bus;
bus.AddSignalWatch ();
bus.Message += HandleMessage;
// Start playing
var ret = Playbin.SetState (State.Playing);
if (ret == StateChangeReturn.Failure) {
Console.WriteLine ("Unable to set the pipeline to the playing state.");
return;
}
// Add a keyboard watch so we get notified of keystrokes
GLib.Idle.Add (HandleKeyboard);
MainLoop = new GLib.MainLoop ();
MainLoop.Run ();
// Free resources
Playbin.SetState (State.Null);
}
static void HandleMessage (object o, MessageArgs args)
{
var msg = args.Message;
switch (msg.Type) {
case MessageType.Error:
GLib.GException err;
string debug;
msg.ParseError (out err, out debug);
Console.WriteLine ("Error received from element {0}: {1}", msg.Src, err.Message);
Console.WriteLine ("Debugging information: {0}", debug != null ? debug : "none");
MainLoop.Quit ();
break;
case MessageType.Eos:
Console.WriteLine ("End-Of-Stream reached.");
MainLoop.Quit ();
break;
case MessageType.StateChanged: {
State oldState, newState, pendingState;
msg.ParseStateChanged (out oldState, out newState, out pendingState);
if (msg.Src == Playbin) {
if (newState == State.Playing) {
// Once we are in the playing state, analyze the streams
AnalyzeStreams ();
}
}
} break;
default:
break;
}
// We want to keep receiving messages
args.RetVal = true;
}
// Extract some metadata from the streams and print it on the screen
static void AnalyzeStreams () {
// Read some properties
NVideo = (int)Playbin ["n-video"];
NAudio = (int)Playbin ["n-audio"];
NText = (int)Playbin ["n-text"];
Console.WriteLine ("{0} video stream(s), {1} audio stream(s), {2} text stream(s)", NVideo, NAudio, NText);
Console.WriteLine ();
for (int i = 0; i < NVideo; i++) {
// Retrieve the stream's video tags
var tags = (TagList)Playbin.Emit ("get-video-tags", new object [] { i });
if (tags != null) {
Console.WriteLine ("video stream {0}", i);
string str;
tags.GetString (Constants.TAG_VIDEO_CODEC, out str);
Console.WriteLine (" codec: {0}", str != null ? str : "unknown");
}
}
Console.WriteLine ();
for (int i = 0; i < NAudio; i++) {
// Retrieve the stream's audio tags
var tags = (TagList)Playbin.Emit ("get-audio-tags", new object [] { i });
if (tags != null) {
Console.WriteLine ("audio stream {0}", i);
string str;
if (tags.GetString (Constants.TAG_AUDIO_CODEC, out str)) {
Console.WriteLine (" codec: {0}", str);
}
if (tags.GetString (Constants.TAG_LANGUAGE_CODE, out str)) {
Console.WriteLine (" language: {0}", str);
}
uint rate;
if (tags.GetUint (Constants.TAG_BITRATE, out rate)) {
Console.WriteLine (" bitrate: {0}", rate);
}
}
}
Console.WriteLine ();
for (int i = 0; i < NText; i++) {
// Retrieve the stream's subtitle tags
var tags = (TagList)Playbin.Emit ("get-text-tags", new object [] { i });
if (tags != null) {
Console.WriteLine ("subtitle stream {0}", i);
string str;
if (tags.GetString (Constants.TAG_LANGUAGE_CODE, out str)) {
Console.WriteLine (" language: {0}", str);
}
}
}
CurrentAudio = (int)Playbin ["current-audio"];
CurrentVideo = (int)Playbin ["current-video"];
CurrentText = (int)Playbin ["current-text"];
Console.WriteLine ();
Console.WriteLine ("Currently playing video stream {0}, audio stream {1} and text stream {2}", CurrentVideo, CurrentAudio, CurrentText);
Console.WriteLine ("Type any number to select a different subtitle stream");
}
// Process keyboard input
static bool HandleKeyboard () {
if (Console.KeyAvailable) {
var key = Console.ReadKey (false);
if (char.IsDigit (key.KeyChar)) {
var digit = int.Parse (key.KeyChar.ToString ());
if (digit < 0 || digit > NText) {
Console.WriteLine ("Index out of bounds");
} else {
// If the input was a valid subtitle stream index, set the current subtitle stream
Console.WriteLine ("Setting current subtitle stream to {0}", digit);
Playbin ["current-text"] = digit;
}
}
}
return true;
}
}
}
|