record mediastream comment

This commit is contained in:
Luke Pulverenti 2016-01-11 11:52:22 -05:00
parent 9fcdcc6eae
commit 81fb823c02
7 changed files with 78 additions and 18 deletions

View File

@ -35,9 +35,10 @@ namespace MediaBrowser.Controller.MediaEncoding
/// Extracts the audio image.
/// </summary>
/// <param name="path">The path.</param>
/// <param name="imageStreamIndex">Index of the image stream.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{Stream}.</returns>
Task<Stream> ExtractAudioImage(string path, CancellationToken cancellationToken);
Task<Stream> ExtractAudioImage(string path, int? imageStreamIndex, CancellationToken cancellationToken);
/// <summary>
/// Extracts the video image.

View File

@ -472,18 +472,18 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// </summary>
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
public Task<Stream> ExtractAudioImage(string path, CancellationToken cancellationToken)
public Task<Stream> ExtractAudioImage(string path, int? imageStreamIndex, CancellationToken cancellationToken)
{
return ExtractImage(new[] { path }, MediaProtocol.File, true, null, null, cancellationToken);
return ExtractImage(new[] { path }, imageStreamIndex, MediaProtocol.File, true, null, null, cancellationToken);
}
public Task<Stream> ExtractVideoImage(string[] inputFiles, MediaProtocol protocol, Video3DFormat? threedFormat,
TimeSpan? offset, CancellationToken cancellationToken)
{
return ExtractImage(inputFiles, protocol, false, threedFormat, offset, cancellationToken);
return ExtractImage(inputFiles, null, protocol, false, threedFormat, offset, cancellationToken);
}
private async Task<Stream> ExtractImage(string[] inputFiles, MediaProtocol protocol, bool isAudio,
private async Task<Stream> ExtractImage(string[] inputFiles, int? imageStreamIndex, MediaProtocol protocol, bool isAudio,
Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken)
{
var resourcePool = isAudio ? _audioImageResourcePool : _videoImageResourcePool;
@ -494,7 +494,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
try
{
return await ExtractImageInternal(inputArgument, protocol, threedFormat, offset, true, resourcePool, cancellationToken).ConfigureAwait(false);
return await ExtractImageInternal(inputArgument, imageStreamIndex, protocol, threedFormat, offset, true, resourcePool, cancellationToken).ConfigureAwait(false);
}
catch (ArgumentException)
{
@ -506,10 +506,10 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
}
return await ExtractImageInternal(inputArgument, protocol, threedFormat, offset, false, resourcePool, cancellationToken).ConfigureAwait(false);
return await ExtractImageInternal(inputArgument, imageStreamIndex, protocol, threedFormat, offset, false, resourcePool, cancellationToken).ConfigureAwait(false);
}
private async Task<Stream> ExtractImageInternal(string inputPath, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, SemaphoreSlim resourcePool, CancellationToken cancellationToken)
private async Task<Stream> ExtractImageInternal(string inputPath, int? imageStreamIndex, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, SemaphoreSlim resourcePool, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(inputPath))
{

View File

@ -141,6 +141,7 @@ namespace MediaBrowser.MediaEncoding.Probing
if (streamInfo.tags != null)
{
stream.Language = GetDictionaryValue(streamInfo.tags, "language");
stream.Comment = GetDictionaryValue(streamInfo.tags, "comment");
}
if (string.Equals(streamInfo.codec_type, "audio", StringComparison.OrdinalIgnoreCase))

View File

@ -30,6 +30,12 @@ namespace MediaBrowser.Model.Entities
/// <value>The language.</value>
public string Language { get; set; }
/// <summary>
/// Gets or sets the comment.
/// </summary>
/// <value>The comment.</value>
public string Comment { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is interlaced.
/// </summary>

View File

@ -1,4 +1,5 @@
using MediaBrowser.Common.Extensions;
using System;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
@ -43,20 +44,27 @@ namespace MediaBrowser.Providers.MediaInfo
{
var audio = (Audio)item;
var imageStreams =
audio.GetMediaSources(false)
.Take(1)
.SelectMany(i => i.MediaStreams)
.Where(i => i.Type == MediaStreamType.EmbeddedImage)
.ToList();
// Can't extract if we didn't find a video stream in the file
if (!audio.GetMediaSources(false).Take(1).SelectMany(i => i.MediaStreams).Any(i => i.Type == MediaStreamType.EmbeddedImage))
if (imageStreams.Count == 0)
{
return Task.FromResult(new DynamicImageResponse { HasImage = false });
}
return GetImage((Audio)item, cancellationToken);
return GetImage((Audio)item, imageStreams, cancellationToken);
}
public async Task<DynamicImageResponse> GetImage(Audio item, CancellationToken cancellationToken)
public async Task<DynamicImageResponse> GetImage(Audio item, List<MediaStream> imageStreams, CancellationToken cancellationToken)
{
var path = GetAudioImagePath(item);
if (!_fileSystem.FileExists(path))
if (!_fileSystem.FileExists(path))
{
var semaphore = GetLock(path);
@ -66,11 +74,16 @@ namespace MediaBrowser.Providers.MediaInfo
try
{
// Check again in case it was saved while waiting for the lock
if (!_fileSystem.FileExists(path))
if (!_fileSystem.FileExists(path))
{
_fileSystem.CreateDirectory(Path.GetDirectoryName(path));
_fileSystem.CreateDirectory(Path.GetDirectoryName(path));
using (var stream = await _mediaEncoder.ExtractAudioImage(item.Path, cancellationToken).ConfigureAwait(false))
var imageStream = imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("front", StringComparison.OrdinalIgnoreCase) != -1) ??
imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("cover", StringComparison.OrdinalIgnoreCase) != -1);
var imageStreamIndex = imageStream == null ? (int?)null : imageStream.Index;
using (var stream = await _mediaEncoder.ExtractAudioImage(item.Path, imageStreamIndex, cancellationToken).ConfigureAwait(false))
{
using (var fileStream = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true))
{

View File

@ -28,6 +28,38 @@ namespace MediaBrowser.Server.Implementations.Persistence
AddKeyFramesColumn();
AddRefFramesCommand();
AddCodecTagColumn();
AddCommentColumn();
}
private void AddCommentColumn()
{
using (var cmd = _connection.CreateCommand())
{
cmd.CommandText = "PRAGMA table_info(mediastreams)";
using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
{
while (reader.Read())
{
if (!reader.IsDBNull(1))
{
var name = reader.GetString(1);
if (string.Equals(name, "Comment", StringComparison.OrdinalIgnoreCase))
{
return;
}
}
}
}
}
var builder = new StringBuilder();
builder.AppendLine("alter table mediastreams");
builder.AppendLine("add column Comment TEXT");
_connection.RunQueries(new[] { builder.ToString() }, _logger);
}
private void AddCodecTagColumn()

View File

@ -127,7 +127,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
_connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false);
var createMediaStreamsTableCommand
= "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, IsCabac BIT NULL, CodecTag TEXT NULL, PRIMARY KEY (ItemId, StreamIndex))";
= "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, IsCabac BIT NULL, CodecTag TEXT NULL, Comment TEXT NULL, PRIMARY KEY (ItemId, StreamIndex))";
string[] queries = {
@ -385,7 +385,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
"IsAnamorphic",
"RefFrames",
"IsCabac",
"CodecTag"
"CodecTag",
"Comment"
};
/// <summary>
@ -2683,6 +2684,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
_saveStreamCommand.GetParameter(index++).Value = stream.IsCabac;
_saveStreamCommand.GetParameter(index++).Value = stream.CodecTag;
_saveStreamCommand.GetParameter(index++).Value = stream.Comment;
_saveStreamCommand.Transaction = transaction;
_saveStreamCommand.ExecuteNonQuery();
@ -2841,6 +2843,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
item.CodecTag = reader.GetString(26);
}
if (!reader.IsDBNull(27))
{
item.Comment = reader.GetString(27);
}
return item;
}