2006-05-21 18:58:44 +00:00
|
|
|
//
|
|
|
|
// DecodeBinTranscoder.cs: sample transcoder using DecodeBin binding
|
|
|
|
//
|
|
|
|
// Authors:
|
|
|
|
// Aaron Bockover (abockover@novell.com)
|
|
|
|
//
|
|
|
|
// (C) 2006 Novell, Inc.
|
|
|
|
//
|
|
|
|
|
|
|
|
using System;
|
|
|
|
using Gst;
|
2009-06-05 18:59:24 +00:00
|
|
|
using Gst.CorePlugins;
|
2009-05-06 12:09:23 +00:00
|
|
|
using Gst.BasePlugins;
|
2006-05-21 18:58:44 +00:00
|
|
|
|
|
|
|
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;
|
2009-06-05 18:59:24 +00:00
|
|
|
private FileSrc filesrc;
|
|
|
|
private FileSink filesink;
|
2006-05-21 18:58:44 +00:00
|
|
|
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)
|
|
|
|
{
|
2009-06-05 18:59:24 +00:00
|
|
|
filesrc.Location = inputFile;
|
|
|
|
filesink.Location = outputFile;
|
2006-05-21 18:58:44 +00:00
|
|
|
|
|
|
|
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");
|
|
|
|
|
2009-06-05 18:59:24 +00:00
|
|
|
filesrc = ElementFactory.Make("filesrc", "filesrc") as FileSrc;
|
|
|
|
filesink = ElementFactory.Make("filesink", "filesink") as FileSink;
|
2006-05-21 18:58:44 +00:00
|
|
|
audioconvert = ElementFactory.Make("audioconvert", "audioconvert");
|
|
|
|
encoder = ElementFactory.Make("wavenc", "wavenc");
|
2009-05-21 19:47:17 +00:00
|
|
|
decodebin = ElementFactory.Make("decodebin", "decodebin") as DecodeBin;
|
2006-05-21 18:58:44 +00:00
|
|
|
decodebin.NewDecodedPad += OnNewDecodedPad;
|
|
|
|
|
2009-05-06 07:54:14 +00:00
|
|
|
pipeline.Add (filesrc, decodebin, audioconvert, encoder, filesink);
|
2006-05-21 18:58:44 +00:00
|
|
|
|
|
|
|
filesrc.Link(decodebin);
|
|
|
|
audioconvert.Link(encoder);
|
|
|
|
encoder.Link(filesink);
|
|
|
|
|
|
|
|
pipeline.Bus.AddWatch(new BusFunc(OnBusMessage));
|
|
|
|
}
|
|
|
|
|
2009-05-26 13:32:27 +00:00
|
|
|
private void OnNewDecodedPad(object o, DecodeBin.NewDecodedPadArgs args)
|
2006-05-21 18:58:44 +00:00
|
|
|
{
|
2009-05-01 13:28:34 +00:00
|
|
|
Pad sinkpad = audioconvert.GetStaticPad("sink");
|
2009-04-04 14:53:59 +00:00
|
|
|
|
2006-05-21 18:58:44 +00:00
|
|
|
if(sinkpad.IsLinked) {
|
|
|
|
return;
|
|
|
|
}
|
2009-04-04 14:53:59 +00:00
|
|
|
|
2006-05-21 18:58:44 +00:00
|
|
|
Caps caps = args.Pad.Caps;
|
2009-04-14 11:42:24 +00:00
|
|
|
Structure structure = caps[0];
|
2006-05-21 18:58:44 +00:00
|
|
|
|
|
|
|
if(!structure.Name.StartsWith("audio")) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
args.Pad.Link(sinkpad);
|
|
|
|
}
|
|
|
|
|
|
|
|
private bool OnBusMessage(Bus bus, Message message)
|
|
|
|
{
|
|
|
|
switch(message.Type) {
|
|
|
|
case MessageType.Error:
|
2009-05-01 13:28:34 +00:00
|
|
|
string msg;
|
|
|
|
Enum err;
|
|
|
|
message.ParseError(out err, out msg);
|
2006-05-21 18:58:44 +00:00
|
|
|
GLib.Source.Remove(progress_timeout);
|
2009-05-01 13:28:34 +00:00
|
|
|
OnError(msg);
|
2006-05-21 18:58:44 +00:00
|
|
|
break;
|
|
|
|
case MessageType.Eos:
|
|
|
|
pipeline.SetState(State.Null);
|
|
|
|
GLib.Source.Remove(progress_timeout);
|
|
|
|
OnFinished();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private bool OnProgressTimeout()
|
|
|
|
{
|
|
|
|
long duration, position;
|
2009-05-01 13:28:34 +00:00
|
|
|
Gst.Format fmt = Gst.Format.Time;
|
2006-05-21 18:58:44 +00:00
|
|
|
|
2009-05-01 13:28:34 +00:00
|
|
|
if(pipeline.QueryDuration(ref fmt, out duration) && fmt == Gst.Format.Time && encoder.QueryPosition(ref fmt, out position) && fmt == Gst.Format.Time) {
|
2006-05-21 18:58:44 +00:00
|
|
|
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();
|
|
|
|
|
2009-04-04 11:33:40 +00:00
|
|
|
transcoder.Error += delegate(object o, ErrorArgs eargs) {
|
|
|
|
Console.WriteLine("Error: {0}", eargs.Error);
|
2006-05-21 18:58:44 +00:00
|
|
|
transcoder.Dispose();
|
|
|
|
loop.Quit();
|
|
|
|
};
|
|
|
|
|
|
|
|
transcoder.Finished += delegate {
|
|
|
|
Console.WriteLine("\nFinished");
|
|
|
|
transcoder.Dispose();
|
|
|
|
loop.Quit();
|
|
|
|
};
|
|
|
|
|
2009-04-04 11:33:40 +00:00
|
|
|
transcoder.Progress += delegate(object o, ProgressArgs pargs) {
|
2006-05-21 18:58:44 +00:00
|
|
|
Console.Write("\rEncoding: {0} / {1} ({2:00.00}%) ",
|
2009-04-04 11:33:40 +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);
|
2006-05-21 18:58:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
transcoder.Transcode(args[0], args[1]);
|
|
|
|
|
|
|
|
loop.Run();
|
|
|
|
}
|
|
|
|
}
|