gstreamer/subprojects/gstreamer-sharp/samples/BasicTutorial9.cs

180 lines
4.6 KiB
C#

// Authors
// Copyright (C) 2014 Stephan Sundermann <stephansundermann@gmail.com>
using System;
using Gst;
using Gst.PbUtils;
using System.Runtime.InteropServices;
namespace GstreamerSharp
{
class Playback
{
static Discoverer Discoverer;
static GLib.MainLoop MainLoop;
// Print a tag in a human-readable format (name: value)
static void PrintTagForeach (TagList tags, string tag, int depth) {
var val = GLib.Value.Empty;
TagList.CopyValue (ref val, tags, tag);
string str;
if (val.Val is string)
str = (string)val.Val;
else
str = Value.Serialize (val);
Console.WriteLine ("{0}{1}: {2}", new string(' ', 2 * depth), Tag.GetNick (tag), str);
}
// Print information regarding a stream
static void PrintStreamInfo (DiscovererStreamInfo info, int depth) {
var caps = info.Caps;
string desc = null;
if (caps != null) {
if (caps.IsFixed)
desc = Gst.PbUtils.Global.PbUtilsGetCodecDescription (caps);
else
desc = caps.ToString ();
}
Console.WriteLine ("{0}{1}: {2}", new string (' ', 2 * depth), info.StreamTypeNick, (desc != null ? desc : ""));
var tags = info.Tags;
if (tags != null) {
Console.WriteLine ("{0}Tags:", new string (' ', 2 * (depth + 1)));
tags.Foreach ((TagForeachFunc)delegate (TagList list, string tag) {
PrintTagForeach (list, tag, depth + 2);
});
}
}
// Print information regarding a stream and its substreams, if any
static void PrintTopology (DiscovererStreamInfo info, int depth) {
if (info == null)
return;
PrintStreamInfo (info, depth);
var next = info.Next;
if (next != null) {
PrintTopology (next, depth + 1);
} else if (info is DiscovererContainerInfo) {
var streams = ((DiscovererContainerInfo)info).Streams;
foreach (var stream in streams) {
PrintTopology (stream, depth + 1);
}
}
}
//This function is called every time the discoverer has information regarding one of the URIs we provided.
static void HandleDiscovered (object disc, DiscoveredArgs args) {
var info = args.Info;
var uri = info.Uri;
var result = info.Result;
var discoverer = (Discoverer)disc;
switch (result) {
case DiscovererResult.UriInvalid:
Console.WriteLine ("Invalid URI '{0}'", uri);
break;
case DiscovererResult.Error:
var err = new GLib.GException (args.Error);
Console.WriteLine ("Discoverer error: {0}", err.Message);
break;
case DiscovererResult.Timeout:
Console.WriteLine ("Timeout");
break;
case DiscovererResult.Busy:
Console.WriteLine ("Busy");
break;
case DiscovererResult.MissingPlugins:{
var s = info.Misc;
if (s != null) {
Console.WriteLine ("Missing plugins: {0}", s);
}
break;
}
case DiscovererResult.Ok:
Console.WriteLine ("Discovered '{0}'", uri);
break;
}
if (result != DiscovererResult.Ok) {
Console.WriteLine ("This URI cannot be played");
return;
}
// If we got no error, show the retrieved information
Console.WriteLine ("\nDuration: {0}", new TimeSpan((long)info.Duration));
var tags = info.Tags;
if (tags != null) {
Console.WriteLine ("Tags:");
tags.Foreach ((TagForeachFunc)delegate (TagList list, string tag) {
PrintTagForeach (list, tag, 1);
});
}
Console.WriteLine ("Seekable: {0}", (info.Seekable ? "yes" : "no"));
Console.WriteLine ();
var sinfo = info.StreamInfo;
if (sinfo == null)
return;
Console.WriteLine ("Stream information:");
PrintTopology (sinfo, 1);
Console.WriteLine ();
}
public static void Main (string[] args)
{
var uri = "http://download.blender.org/durian/trailer/sintel_trailer-1080p.mp4";
// if a URI was provided, use it instead of the default one
if (args.Length > 1) {
uri = args[0];
}
// Initialize GStreamer
Gst.Application.Init (ref args);
Console.WriteLine ("Discovering '{0}'", uri);
// Instantiate the Discoverer
Discoverer = new Discoverer (5L * Gst.Constants.SECOND);
// Connect to the interesting signals
Discoverer.Discovered += HandleDiscovered;
Discoverer.Finished += (sender, e) => {
Console.WriteLine ("Finished discovering");
MainLoop.Quit ();
};
// Start the discoverer process (nothing to do yet)
Discoverer.Start ();
// Add a request to process asynchronously the URI passed through the command line
if (!Discoverer.DiscoverUriAsync (uri)) {
Console.WriteLine ("Failed to start discovering URI '{0}'", uri);
return;
}
// Create a GLib Main Loop and set it to run, so we can wait for the signals
MainLoop = new GLib.MainLoop ();
MainLoop.Run ();
// Stop the discoverer process
Discoverer.Stop ();
}
}
}