Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get thumbnail as byte array from stdout #62

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions MediaToolkit src/MediaToolkit.Test/ConvertTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,29 @@ public void Can_GetThumbnail()
Assert.That(File.Exists(outputPath));
}

[TestCase]
public void Can_GetThumbnailAsByteArray()
{
var inputFile = new MediaFile { Filename = _inputFilePath };
var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var localMediaToolkitFfMpeg = Path.Combine(localAppData, "MediaToolkit", "ffmpeg.exe");

using (var engine = new Engine(localMediaToolkitFfMpeg))
{
engine.ConvertProgressEvent += engine_ConvertProgressEvent;
engine.ConversionCompleteEvent += engine_ConversionCompleteEvent;

engine.GetMetadata(inputFile);

var options = new ConversionOptions
{
Seek = TimeSpan.FromSeconds(inputFile.Metadata.Duration.TotalSeconds / 2)
};
var thumbnailByteArray = engine.GetThumbnail(inputFile, options);
Assert.AreEqual(9530, thumbnailByteArray.Length);
}
}

[TestCase]
public void Can_GetThumbnailFromHTTPLink()
{
Expand Down
15 changes: 15 additions & 0 deletions MediaToolkit src/MediaToolkit/CommandBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ internal static string Serialize(EngineParameters engineParameters)

case FFmpegTask.GetThumbnail:
return GetThumbnail(engineParameters.InputFile, engineParameters.OutputFile, engineParameters.ConversionOptions);
case FFmpegTask.GetThumbnailStream:
return GetThumbnail(engineParameters.InputFile, engineParameters.ConversionOptions);
default:
throw new ArgumentOutOfRangeException();
}
Expand All @@ -43,6 +45,19 @@ private static string GetThumbnail(MediaFile inputFile, MediaFile outputFile, Co
return commandBuilder.AppendFormat(" \"{0}\" ", outputFile.Filename).ToString();
}

private static string GetThumbnail(MediaFile inputFile, ConversionOptions conversionOptions)
{
var commandBuilder = new StringBuilder();

commandBuilder.AppendFormat(CultureInfo.InvariantCulture, " -ss {0} ", conversionOptions.Seek.GetValueOrDefault(TimeSpan.FromSeconds(1)).TotalSeconds);

commandBuilder.AppendFormat(" -i \"{0}\"", inputFile.Filename);
commandBuilder.AppendFormat(" -vframes {0}", 1);
commandBuilder.AppendFormat(" -f mjpeg pipe:1");
return commandBuilder.ToString();
}


private static string Convert(MediaFile inputFile, MediaFile outputFile, ConversionOptions conversionOptions)
{
var commandBuilder = new StringBuilder();
Expand Down
35 changes: 35 additions & 0 deletions MediaToolkit src/MediaToolkit/Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public class Engine : EngineBase
/// </summary>
public event EventHandler<ConversionCompleteEventArgs> ConversionCompleteEvent;

private byte[] thumbnailByteArray { get; set; }

public Engine()
{

Expand Down Expand Up @@ -118,6 +120,20 @@ public void GetThumbnail(MediaFile inputFile, MediaFile outputFile, ConversionOp

this.FFmpegEngine(engineParams);
}

public byte[] GetThumbnail(MediaFile inputFile, ConversionOptions options)
{
EngineParameters engineParams = new EngineParameters
{
InputFile = inputFile,
ConversionOptions = options,
Task = FFmpegTask.GetThumbnailStream,
ReturningStandardOutput = true
};

this.FFmpegEngine(engineParams);
return this.thumbnailByteArray;
}

#region Private method - Helpers

Expand Down Expand Up @@ -291,6 +307,25 @@ private void StartFFmpegProcess(EngineParameters engineParameters)
}
};

if(engineParameters.ReturningStandardOutput)
{
FileStream baseStream = this.FFmpegProcess.StandardOutput.BaseStream as FileStream;
this.thumbnailByteArray = null;
int lastRead = 0;

using (MemoryStream ms = new MemoryStream())
{
byte[] buffer = new byte[4096];
do
{
lastRead = baseStream.Read(buffer, 0, buffer.Length);
ms.Write(buffer, 0, lastRead);
} while (lastRead > 0);

this.thumbnailByteArray = ms.ToArray();
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not try reading from baseStream all in one go?

byte[] buffer = new byte[baseStream.Length];
baseStream.Read(buffer, 0, buffer.Length);
this.thumbnailByteArray = buffer;

Only reason I could think as to why it wouldn't work is if baseStream.CanSeek is false.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd copied a code snippet. In light of your comments I've changed how the file stream is copied to the memory stream. Thanks.

}

this.FFmpegProcess.BeginErrorReadLine();
this.FFmpegProcess.WaitForExit();

Expand Down
4 changes: 4 additions & 0 deletions MediaToolkit src/MediaToolkit/EngineParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ internal bool HasCustomArguments
}
}

/// -------------------------------------------------------------------------------------------------
/// <summary> Indicates whether we will be returning from stdout. </summary>
/// <value> True if returning from stdout, false otherwise. </value>
internal bool ReturningStandardOutput { get; set; }
/// -------------------------------------------------------------------------------------------------
/// <summary> Gets or sets options for controlling the conversion. </summary>
/// <value> Options that control the conversion. </value>
Expand Down
5 changes: 4 additions & 1 deletion MediaToolkit src/MediaToolkit/FFmpegTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ internal enum FFmpegTask
GetMetaData,

/// <summary> An enum constant representing the get thumbnail option. </summary>
GetThumbnail
GetThumbnail,

/// <summary> An enum constant representing the get thumbnail via a byte stream option. </summary>
GetThumbnailStream
}
}