gstreamer/samples/BasicTutorial4.cs
Thibault Saunier c40730fe93 samples: Fix Tutorial4 by making it actually seek at some point.
Thanks to "tomislavtustonic" for the bug report and patch.

Also make the seek "Flushing" as the C tutorial.

https://bugzilla.gnome.org/show_bug.cgi?id=796184
2018-05-17 21:39:29 -04:00

136 lines
No EOL
4 KiB
C#

// 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.Write("Position {0} / {1}\r", new TimeSpan (current), new TimeSpan (duration));
if (seekEnabled && !seekDone && current > 10L * Constants.SECOND) {
Console.WriteLine ("\nRead 10s, performing seek...");
playbin.SeekSimple (fmt, SeekFlags.KeyUnit | SeekFlags.Flush, 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;
}
}
}
}