gstreamer/samples/PlaybackTutorial2.cs
2014-08-08 00:57:34 +02:00

185 lines
No EOL
5.5 KiB
C#

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