gstreamer/samples/DecodeBinTranscoder.cs
Sebastian Dröge 8ece992223 Don't allow subclassing of element bindings
...and clean up/simplify the DynamicSignal stuff.
2009-06-05 20:59:24 +02:00

199 lines
5.4 KiB
C#

//
// DecodeBinTranscoder.cs: sample transcoder using DecodeBin binding
//
// Authors:
// Aaron Bockover (abockover@novell.com)
//
// (C) 2006 Novell, Inc.
//
using System;
using Gst;
using Gst.CorePlugins;
using Gst.BasePlugins;
public delegate void ErrorHandler(object o, ErrorArgs args);
public delegate void ProgressHandler(object o, ProgressArgs args);
public class ErrorArgs : EventArgs
{
public string Error;
}
public class ProgressArgs : EventArgs
{
public long Duration;
public long Position;
}
public class DecodeBinTranscoder : IDisposable
{
private Pipeline pipeline;
private FileSrc filesrc;
private FileSink filesink;
private Element audioconvert;
private Element encoder;
private DecodeBin decodebin;
private uint progress_timeout;
public event EventHandler Finished;
public event ErrorHandler Error;
public event ProgressHandler Progress;
public DecodeBinTranscoder()
{
ConstructPipeline();
}
public void Transcode(string inputFile, string outputFile)
{
filesrc.Location = inputFile;
filesink.Location = outputFile;
pipeline.SetState(State.Playing);
progress_timeout = GLib.Timeout.Add(250, OnProgressTimeout);
}
public void Dispose()
{
pipeline.Dispose();
}
protected virtual void OnFinished()
{
EventHandler handler = Finished;
if(handler != null) {
handler(this, new EventArgs());
}
}
protected virtual void OnError(string error)
{
ErrorHandler handler = Error;
if(handler != null) {
ErrorArgs args = new ErrorArgs();
args.Error = error;
handler(this, args);
}
}
protected virtual void OnProgress(long position, long duration)
{
ProgressHandler handler = Progress;
if(handler != null) {
ProgressArgs args = new ProgressArgs();
args.Position = position;
args.Duration = duration;
handler(this, args);
}
}
private void ConstructPipeline()
{
pipeline = new Pipeline("pipeline");
filesrc = ElementFactory.Make("filesrc", "filesrc") as FileSrc;
filesink = ElementFactory.Make("filesink", "filesink") as FileSink;
audioconvert = ElementFactory.Make("audioconvert", "audioconvert");
encoder = ElementFactory.Make("wavenc", "wavenc");
decodebin = ElementFactory.Make("decodebin", "decodebin") as DecodeBin;
decodebin.NewDecodedPad += OnNewDecodedPad;
pipeline.Add (filesrc, decodebin, audioconvert, encoder, filesink);
filesrc.Link(decodebin);
audioconvert.Link(encoder);
encoder.Link(filesink);
pipeline.Bus.AddWatch(new BusFunc(OnBusMessage));
}
private void OnNewDecodedPad(object o, DecodeBin.NewDecodedPadArgs args)
{
Pad sinkpad = audioconvert.GetStaticPad("sink");
if(sinkpad.IsLinked) {
return;
}
Caps caps = args.Pad.Caps;
Structure structure = caps[0];
if(!structure.Name.StartsWith("audio")) {
return;
}
args.Pad.Link(sinkpad);
}
private bool OnBusMessage(Bus bus, Message message)
{
switch(message.Type) {
case MessageType.Error:
string msg;
Enum err;
message.ParseError(out err, out msg);
GLib.Source.Remove(progress_timeout);
OnError(msg);
break;
case MessageType.Eos:
pipeline.SetState(State.Null);
GLib.Source.Remove(progress_timeout);
OnFinished();
break;
}
return true;
}
private bool OnProgressTimeout()
{
long duration, position;
Gst.Format fmt = Gst.Format.Time;
if(pipeline.QueryDuration(ref fmt, out duration) && fmt == Gst.Format.Time && encoder.QueryPosition(ref fmt, out position) && fmt == Gst.Format.Time) {
OnProgress(position, duration);
}
return true;
}
private static GLib.MainLoop loop;
public static void Main(string [] args)
{
if(args.Length < 2) {
Console.WriteLine("Usage: mono decodebin-transcoder.exe <input-file> <output-file>");
return;
}
Gst.Application.Init();
loop = new GLib.MainLoop();
DecodeBinTranscoder transcoder = new DecodeBinTranscoder();
transcoder.Error += delegate(object o, ErrorArgs eargs) {
Console.WriteLine("Error: {0}", eargs.Error);
transcoder.Dispose();
loop.Quit();
};
transcoder.Finished += delegate {
Console.WriteLine("\nFinished");
transcoder.Dispose();
loop.Quit();
};
transcoder.Progress += delegate(object o, ProgressArgs pargs) {
Console.Write("\rEncoding: {0} / {1} ({2:00.00}%) ",
new TimeSpan((pargs.Position / (long) Clock.Second) * TimeSpan.TicksPerSecond),
new TimeSpan((pargs.Duration / (long) Clock.Second) * TimeSpan.TicksPerSecond),
((double)pargs.Position / (double)pargs.Duration) * 100.0);
};
transcoder.Transcode(args[0], args[1]);
loop.Run();
}
}