mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 19:21:06 +00:00
180 lines
4.6 KiB
C#
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 ();
|
||
|
}
|
||
|
}
|
||
|
}
|