mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-09-06 05:47:14 -04:00
create separate media encoding project
This commit is contained in:
parent
c2537a57eb
commit
fb22901d38
@ -316,6 +316,7 @@ namespace MediaBrowser.Api.Playback
|
||||
/// </summary>
|
||||
/// <param name="state">The state.</param>
|
||||
/// <param name="videoCodec">The video codec.</param>
|
||||
/// <param name="isHls">if set to <c>true</c> [is HLS].</param>
|
||||
/// <returns>System.String.</returns>
|
||||
protected string GetVideoQualityParam(StreamState state, string videoCodec, bool isHls)
|
||||
{
|
||||
@ -340,20 +341,17 @@ namespace MediaBrowser.Api.Playback
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isHls)
|
||||
switch (qualitySetting)
|
||||
{
|
||||
switch (qualitySetting)
|
||||
{
|
||||
case EncodingQuality.HighSpeed:
|
||||
param += " -crf 23";
|
||||
break;
|
||||
case EncodingQuality.HighQuality:
|
||||
param += " -crf 20";
|
||||
break;
|
||||
case EncodingQuality.MaxQuality:
|
||||
param += " -crf 18";
|
||||
break;
|
||||
}
|
||||
case EncodingQuality.HighSpeed:
|
||||
param += " -crf 23";
|
||||
break;
|
||||
case EncodingQuality.HighQuality:
|
||||
param += " -crf 20";
|
||||
break;
|
||||
case EncodingQuality.MaxQuality:
|
||||
param += " -crf 18";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1032,11 +1030,6 @@ namespace MediaBrowser.Api.Playback
|
||||
{
|
||||
var hasFixedResolution = state.VideoRequest.HasFixedResolution;
|
||||
|
||||
if (isHls)
|
||||
{
|
||||
return string.Format(" -b:v {0} -maxrate ({0}*.80) -bufsize {0}", bitrate.Value.ToString(UsCulture));
|
||||
}
|
||||
|
||||
if (string.Equals(videoCodec, "libvpx", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (hasFixedResolution)
|
||||
@ -1047,7 +1040,6 @@ namespace MediaBrowser.Api.Playback
|
||||
// With vpx when crf is used, b:v becomes a max rate
|
||||
// https://trac.ffmpeg.org/wiki/vpxEncodingGuide
|
||||
return string.Format(" -b:v {0}", bitrate.Value.ToString(UsCulture));
|
||||
//return string.Format(" -minrate:v ({0}*.95) -maxrate:v ({0}*1.05) -bufsize:v {0} -b:v {0}", bitrate.Value.ToString(UsCulture));
|
||||
}
|
||||
|
||||
if (string.Equals(videoCodec, "msmpeg4", StringComparison.OrdinalIgnoreCase))
|
||||
@ -1055,13 +1047,17 @@ namespace MediaBrowser.Api.Playback
|
||||
return string.Format(" -b:v {0}", bitrate.Value.ToString(UsCulture));
|
||||
}
|
||||
|
||||
|
||||
// H264
|
||||
if (hasFixedResolution)
|
||||
{
|
||||
if (isHls)
|
||||
{
|
||||
return string.Format(" -b:v {0} -maxrate ({0}*.80) -bufsize {0}", bitrate.Value.ToString(UsCulture));
|
||||
}
|
||||
|
||||
return string.Format(" -b:v {0}", bitrate.Value.ToString(UsCulture));
|
||||
}
|
||||
|
||||
|
||||
return string.Format(" -maxrate {0} -bufsize {1}",
|
||||
bitrate.Value.ToString(UsCulture),
|
||||
(bitrate.Value * 2).ToString(UsCulture));
|
||||
|
@ -200,7 +200,7 @@ namespace MediaBrowser.Api.Playback.Hls
|
||||
builder.AppendLine("#EXTM3U");
|
||||
|
||||
// Pad a little to satisfy the apple hls validator
|
||||
var paddedBitrate = Convert.ToInt32(bitrate * 1.05);
|
||||
var paddedBitrate = Convert.ToInt32(bitrate * 1.15);
|
||||
|
||||
// Main stream
|
||||
builder.AppendLine("#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=" + paddedBitrate.ToString(UsCulture));
|
||||
|
@ -266,6 +266,11 @@ namespace MediaBrowser.Api.Playback.Progressive
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of the estimated content.
|
||||
/// </summary>
|
||||
/// <param name="state">The state.</param>
|
||||
/// <returns>System.Nullable{System.Int64}.</returns>
|
||||
private long? GetEstimatedContentLength(StreamState state)
|
||||
{
|
||||
var totalBitrate = 0;
|
||||
|
@ -24,16 +24,23 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
string Version { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Extracts the image.
|
||||
/// Extracts the audio image.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{Stream}.</returns>
|
||||
Task<Stream> ExtractAudioImage(string path, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Extracts the video image.
|
||||
/// </summary>
|
||||
/// <param name="inputFiles">The input files.</param>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="isAudio">if set to <c>true</c> [is audio].</param>
|
||||
/// <param name="threedFormat">The threed format.</param>
|
||||
/// <param name="offset">The offset.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{Stream}.</returns>
|
||||
Task<Stream> ExtractImage(string[] inputFiles, InputType type, bool isAudio, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken);
|
||||
Task<Stream> ExtractVideoImage(string[] inputFiles, InputType type, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Extracts the text subtitle.
|
||||
|
@ -197,7 +197,7 @@ namespace MediaBrowser.Dlna
|
||||
throw new ArgumentNullException("headers");
|
||||
}
|
||||
|
||||
return GetProfiles().FirstOrDefault(i => IsMatch(headers, i.Identification));
|
||||
return GetProfiles().FirstOrDefault(i => i.Identification != null && IsMatch(headers, i.Identification));
|
||||
}
|
||||
|
||||
private bool IsMatch(IDictionary<string, string> headers, DeviceIdentification profileInfo)
|
||||
|
@ -631,7 +631,7 @@ namespace MediaBrowser.Dlna.PlayTo
|
||||
RendererCommands = TransportCommands.Create(document);
|
||||
}
|
||||
|
||||
internal TransportCommands AvCommands
|
||||
private TransportCommands AvCommands
|
||||
{
|
||||
get;
|
||||
set;
|
||||
|
@ -57,24 +57,6 @@ namespace MediaBrowser.Dlna.Profiles
|
||||
Type = DlnaProfileType.Video
|
||||
}
|
||||
};
|
||||
|
||||
CodecProfiles = new[]
|
||||
{
|
||||
new CodecProfile
|
||||
{
|
||||
Type = CodecType.VideoCodec,
|
||||
Conditions = new []
|
||||
{
|
||||
new ProfileCondition
|
||||
{
|
||||
Condition = ProfileConditionType.LessThanEqual,
|
||||
Property = ProfileConditionValue.VideoLevel,
|
||||
Value = "3",
|
||||
IsRequired = false
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -229,13 +229,6 @@ namespace MediaBrowser.Dlna.Profiles
|
||||
Property = ProfileConditionValue.VideoBitrate,
|
||||
Value = "10240000",
|
||||
IsRequired = false
|
||||
},
|
||||
new ProfileCondition
|
||||
{
|
||||
Condition = ProfileConditionType.LessThanEqual,
|
||||
Property = ProfileConditionValue.VideoLevel,
|
||||
Value = "3",
|
||||
IsRequired = false
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -271,13 +264,6 @@ namespace MediaBrowser.Dlna.Profiles
|
||||
Property = ProfileConditionValue.VideoBitrate,
|
||||
Value = "15360000",
|
||||
IsRequired = false
|
||||
},
|
||||
new ProfileCondition
|
||||
{
|
||||
Condition = ProfileConditionType.LessThanEqual,
|
||||
Property = ProfileConditionValue.VideoLevel,
|
||||
Value = "3",
|
||||
IsRequired = false
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -30,12 +30,5 @@
|
||||
</TranscodingProfile>
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles />
|
||||
<CodecProfiles>
|
||||
<CodecProfile type="VideoCodec">
|
||||
<Conditions>
|
||||
<ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
|
||||
</Conditions>
|
||||
</CodecProfile>
|
||||
</CodecProfiles>
|
||||
<MediaProfiles />
|
||||
</Profile>
|
@ -34,12 +34,5 @@
|
||||
</TranscodingProfile>
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles />
|
||||
<CodecProfiles>
|
||||
<CodecProfile type="VideoCodec">
|
||||
<Conditions>
|
||||
<ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
|
||||
</Conditions>
|
||||
</CodecProfile>
|
||||
</CodecProfiles>
|
||||
<MediaProfiles />
|
||||
</Profile>
|
@ -34,12 +34,5 @@
|
||||
</TranscodingProfile>
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles />
|
||||
<CodecProfiles>
|
||||
<CodecProfile type="VideoCodec">
|
||||
<Conditions>
|
||||
<ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
|
||||
</Conditions>
|
||||
</CodecProfile>
|
||||
</CodecProfiles>
|
||||
<MediaProfiles />
|
||||
</Profile>
|
@ -73,7 +73,6 @@
|
||||
<ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
|
||||
<ProfileCondition condition="LessThanEqual" property="VideoLevel" value="41" isRequired="false" />
|
||||
<ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="10240000" isRequired="false" />
|
||||
<ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
|
||||
</Conditions>
|
||||
</CodecProfile>
|
||||
<CodecProfile type="VideoCodec" codec="wmv2,wmv3,vc1">
|
||||
@ -82,7 +81,6 @@
|
||||
<ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
|
||||
<ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="30" isRequired="false" />
|
||||
<ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="15360000" isRequired="false" />
|
||||
<ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
|
||||
</Conditions>
|
||||
</CodecProfile>
|
||||
<CodecProfile type="VideoAudioCodec" codec="ac3,wmav2,wmapro">
|
||||
|
@ -32,13 +32,6 @@
|
||||
</TranscodingProfile>
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles />
|
||||
<CodecProfiles>
|
||||
<CodecProfile type="VideoCodec">
|
||||
<Conditions>
|
||||
<ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
|
||||
</Conditions>
|
||||
</CodecProfile>
|
||||
</CodecProfiles>
|
||||
<MediaProfiles>
|
||||
<MediaProfile container="avi" type="Video" mimeType="video/x-msvideo">
|
||||
<Conditions />
|
||||
|
@ -36,12 +36,5 @@
|
||||
</TranscodingProfile>
|
||||
</TranscodingProfiles>
|
||||
<ContainerProfiles />
|
||||
<CodecProfiles>
|
||||
<CodecProfile type="VideoCodec">
|
||||
<Conditions>
|
||||
<ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
|
||||
</Conditions>
|
||||
</CodecProfile>
|
||||
</CodecProfiles>
|
||||
<MediaProfiles />
|
||||
</Profile>
|
@ -5,7 +5,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.BdInfo
|
||||
namespace MediaBrowser.MediaEncoding.BdInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Class BdInfoExaminer
|
@ -6,17 +6,15 @@ using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
namespace MediaBrowser.MediaEncoding.Encoder
|
||||
{
|
||||
/// <summary>
|
||||
/// Class MediaEncoder
|
||||
@ -53,6 +51,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
/// The FF probe resource pool
|
||||
/// </summary>
|
||||
private readonly SemaphoreSlim _ffProbeResourcePool = new SemaphoreSlim(2, 2);
|
||||
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public string FFMpegPath { get; private set; }
|
||||
@ -62,7 +61,8 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
public string Version { get; private set; }
|
||||
|
||||
public MediaEncoder(ILogger logger, IApplicationPaths appPaths,
|
||||
IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version, IFileSystem fileSystem)
|
||||
IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version,
|
||||
IFileSystem fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_appPaths = appPaths;
|
||||
@ -85,7 +85,8 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
/// <summary>
|
||||
/// The _semaphoreLocks
|
||||
/// </summary>
|
||||
private readonly ConcurrentDictionary<string, SemaphoreSlim> _semaphoreLocks = new ConcurrentDictionary<string, SemaphoreSlim>();
|
||||
private readonly ConcurrentDictionary<string, SemaphoreSlim> _semaphoreLocks =
|
||||
new ConcurrentDictionary<string, SemaphoreSlim>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the lock.
|
||||
@ -106,10 +107,10 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
public Task<InternalMediaInfoResult> GetMediaInfo(string[] inputFiles, InputType type, bool isAudio,
|
||||
CancellationToken cancellationToken)
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return GetMediaInfoInternal(GetInputArgument(inputFiles, type), !isAudio,
|
||||
GetProbeSizeArgument(type), cancellationToken);
|
||||
GetProbeSizeArgument(type), cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -172,8 +173,8 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
/// <returns>Task{MediaInfoResult}.</returns>
|
||||
/// <exception cref="System.ApplicationException"></exception>
|
||||
private async Task<InternalMediaInfoResult> GetMediaInfoInternal(string inputPath, bool extractChapters,
|
||||
string probeSizeArgument,
|
||||
CancellationToken cancellationToken)
|
||||
string probeSizeArgument,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var args = extractChapters
|
||||
? "{0} -i {1} -threads 0 -v info -print_format json -show_streams -show_chapters -show_format"
|
||||
@ -191,7 +192,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
RedirectStandardError = true,
|
||||
FileName = FFProbePath,
|
||||
Arguments = string.Format(args,
|
||||
probeSizeArgument, inputPath).Trim(),
|
||||
probeSizeArgument, inputPath).Trim(),
|
||||
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
ErrorDialog = false
|
||||
@ -225,7 +226,8 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
{
|
||||
process.BeginErrorReadLine();
|
||||
|
||||
result = _jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream);
|
||||
result =
|
||||
_jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@ -295,7 +297,8 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
/// <param name="language">The language.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
public async Task ConvertTextSubtitleToAss(string inputPath, string outputPath, string language, CancellationToken cancellationToken)
|
||||
public async Task ConvertTextSubtitleToAss(string inputPath, string outputPath, string language,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var semaphore = GetLock(outputPath);
|
||||
|
||||
@ -340,33 +343,35 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
}
|
||||
|
||||
|
||||
var encodingParam = string.IsNullOrEmpty(language) ? string.Empty :
|
||||
GetSubtitleLanguageEncodingParam(language) + " ";
|
||||
var encodingParam = string.IsNullOrEmpty(language)
|
||||
? string.Empty
|
||||
: GetSubtitleLanguageEncodingParam(language) + " ";
|
||||
|
||||
var process = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
RedirectStandardOutput = false,
|
||||
RedirectStandardError = true,
|
||||
RedirectStandardOutput = false,
|
||||
RedirectStandardError = true,
|
||||
|
||||
CreateNoWindow = true,
|
||||
UseShellExecute = false,
|
||||
FileName = FFMpegPath,
|
||||
Arguments =
|
||||
string.Format("{0} -i \"{1}\" -c:s ass \"{2}\"", encodingParam, inputPath, outputPath),
|
||||
CreateNoWindow = true,
|
||||
UseShellExecute = false,
|
||||
FileName = FFMpegPath,
|
||||
Arguments =
|
||||
string.Format("{0} -i \"{1}\" -c:s ass \"{2}\"", encodingParam, inputPath, outputPath),
|
||||
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
ErrorDialog = false
|
||||
}
|
||||
};
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
ErrorDialog = false
|
||||
}
|
||||
};
|
||||
|
||||
_logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
|
||||
|
||||
var logFilePath = Path.Combine(_appPaths.LogDirectoryPath, "ffmpeg-sub-convert-" + Guid.NewGuid() + ".txt");
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(logFilePath));
|
||||
|
||||
var logFileStream = _fileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, true);
|
||||
var logFileStream = _fileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read,
|
||||
true);
|
||||
|
||||
try
|
||||
{
|
||||
@ -525,7 +530,8 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentException">Must use inputPath list overload</exception>
|
||||
public async Task ExtractTextSubtitle(string[] inputFiles, InputType type, int subtitleStreamIndex, bool copySubtitleStream, string outputPath, CancellationToken cancellationToken)
|
||||
public async Task ExtractTextSubtitle(string[] inputFiles, InputType type, int subtitleStreamIndex,
|
||||
bool copySubtitleStream, string outputPath, CancellationToken cancellationToken)
|
||||
{
|
||||
var semaphore = GetLock(outputPath);
|
||||
|
||||
@ -535,7 +541,9 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
{
|
||||
if (!File.Exists(outputPath))
|
||||
{
|
||||
await ExtractTextSubtitleInternal(GetInputArgument(inputFiles, type), subtitleStreamIndex, copySubtitleStream, outputPath, cancellationToken).ConfigureAwait(false);
|
||||
await
|
||||
ExtractTextSubtitleInternal(GetInputArgument(inputFiles, type), subtitleStreamIndex,
|
||||
copySubtitleStream, outputPath, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
finally
|
||||
@ -559,7 +567,8 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
/// or
|
||||
/// cancellationToken</exception>
|
||||
/// <exception cref="System.ApplicationException"></exception>
|
||||
private async Task ExtractTextSubtitleInternal(string inputPath, int subtitleStreamIndex, bool copySubtitleStream, string outputPath, CancellationToken cancellationToken)
|
||||
private async Task ExtractTextSubtitleInternal(string inputPath, int subtitleStreamIndex,
|
||||
bool copySubtitleStream, string outputPath, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrEmpty(inputPath))
|
||||
{
|
||||
@ -571,11 +580,13 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
throw new ArgumentNullException("outputPath");
|
||||
}
|
||||
|
||||
string processArgs = string.Format("-i {0} -map 0:{1} -an -vn -c:s ass \"{2}\"", inputPath, subtitleStreamIndex, outputPath);
|
||||
string processArgs = string.Format("-i {0} -map 0:{1} -an -vn -c:s ass \"{2}\"", inputPath,
|
||||
subtitleStreamIndex, outputPath);
|
||||
|
||||
if (copySubtitleStream)
|
||||
{
|
||||
processArgs = string.Format("-i {0} -map 0:{1} -an -vn -c:s copy \"{2}\"", inputPath, subtitleStreamIndex, outputPath);
|
||||
processArgs = string.Format("-i {0} -map 0:{1} -an -vn -c:s copy \"{2}\"", inputPath,
|
||||
subtitleStreamIndex, outputPath);
|
||||
}
|
||||
|
||||
var process = new Process
|
||||
@ -600,7 +611,8 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
var logFilePath = Path.Combine(_appPaths.LogDirectoryPath, "ffmpeg-sub-extract-" + Guid.NewGuid() + ".txt");
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(logFilePath));
|
||||
|
||||
var logFileStream = _fileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, true);
|
||||
var logFileStream = _fileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read,
|
||||
true);
|
||||
|
||||
try
|
||||
{
|
||||
@ -715,7 +727,18 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Stream> ExtractImage(string[] inputFiles, InputType type, bool isAudio,
|
||||
public Task<Stream> ExtractAudioImage(string path, CancellationToken cancellationToken)
|
||||
{
|
||||
return ExtractImage(new[] { path }, InputType.File, true, null, null, cancellationToken);
|
||||
}
|
||||
|
||||
public Task<Stream> ExtractVideoImage(string[] inputFiles, InputType type, Video3DFormat? threedFormat,
|
||||
TimeSpan? offset, CancellationToken cancellationToken)
|
||||
{
|
||||
return ExtractImage(inputFiles, type, false, threedFormat, offset, cancellationToken);
|
||||
}
|
||||
|
||||
private async Task<Stream> ExtractImage(string[] inputFiles, InputType type, bool isAudio,
|
||||
Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken)
|
||||
{
|
||||
var resourcePool = isAudio ? _audioImageResourcePool : _videoImageResourcePool;
|
||||
@ -773,7 +796,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
}
|
||||
|
||||
// Use ffmpeg to sample 100 (we can drop this if required using thumbnail=50 for 50 frames) frames and pick the best thumbnail. Have a fall back just in case.
|
||||
var args = useIFrame ? string.Format("-i {0} -threads 0 -v quiet -vframes 1 -vf \"{2},thumbnail\" -f image2 \"{1}\"", inputPath, "-", vf) :
|
||||
var args = useIFrame ? string.Format("-i {0} -threads 0 -v quiet -vframes 1 -vf \"{2},thumbnail=80\" -f image2 \"{1}\"", inputPath, "-", vf) :
|
||||
string.Format("-i {0} -threads 0 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, "-", vf);
|
||||
|
||||
var probeSize = GetProbeSizeArgument(type);
|
||||
@ -834,7 +857,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
_logger.ErrorException("Error killing process", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
resourcePool.Release();
|
||||
|
||||
var exitCode = ranToCompletion ? process.ExitCode : -1;
|
80
MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
Normal file
80
MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj
Normal file
@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MediaBrowser.MediaEncoding</RootNamespace>
|
||||
<AssemblyName>MediaBrowser.MediaEncoding</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
||||
<RestorePackages>true</RestorePackages>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="BDInfo">
|
||||
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\BDInfo.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DvdLib">
|
||||
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\DvdLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BdInfo\BdInfoExaminer.cs" />
|
||||
<Compile Include="Encoder\MediaEncoder.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
|
||||
<Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
|
||||
<Name>MediaBrowser.Common</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj">
|
||||
<Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project>
|
||||
<Name>MediaBrowser.Controller</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
|
||||
<Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
|
||||
<Name>MediaBrowser.Model</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
36
MediaBrowser.MediaEncoding/Properties/AssemblyInfo.cs
Normal file
36
MediaBrowser.MediaEncoding/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("MediaBrowser.MediaEncoding")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("MediaBrowser.MediaEncoding")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2014")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("05f49ab9-2a90-4332-9d41-7817a9cccd90")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
4
MediaBrowser.MediaEncoding/packages.config
Normal file
4
MediaBrowser.MediaEncoding/packages.config
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="MediaBrowser.BdInfo" version="1.0.0.10" targetFramework="net45" />
|
||||
</packages>
|
@ -94,7 +94,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
|
||||
using (var stream = await _mediaEncoder.ExtractImage(new[] { item.Path }, InputType.File, true, null, null, cancellationToken).ConfigureAwait(false))
|
||||
using (var stream = await _mediaEncoder.ExtractAudioImage(item.Path, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
using (var fileStream = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true))
|
||||
{
|
||||
|
@ -113,8 +113,6 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var idString = item.Id.ToString("N");
|
||||
var cachePath = Path.Combine(_appPaths.CachePath,
|
||||
"ffprobe-video",
|
||||
|
@ -93,7 +93,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
||||
|
||||
var inputPath = MediaEncoderHelpers.GetInputArgument(item.Path, item.LocationType == LocationType.Remote, item.VideoType, item.IsoType, isoMount, item.PlayableStreamFileNames, out type);
|
||||
|
||||
var stream = await _mediaEncoder.ExtractImage(inputPath, type, false, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false);
|
||||
var stream = await _mediaEncoder.ExtractVideoImage(inputPath, type, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return new DynamicImageResponse
|
||||
{
|
||||
|
@ -249,17 +249,24 @@ namespace MediaBrowser.Server.Implementations.IO
|
||||
// Creating a FileSystemWatcher over the LAN can take hundreds of milliseconds, so wrap it in a Task to do them all in parallel
|
||||
Task.Run(() =>
|
||||
{
|
||||
var newWatcher = new FileSystemWatcher(path, "*") { IncludeSubdirectories = true, InternalBufferSize = 32767 };
|
||||
|
||||
newWatcher.Created += watcher_Changed;
|
||||
newWatcher.Deleted += watcher_Changed;
|
||||
newWatcher.Renamed += watcher_Changed;
|
||||
newWatcher.Changed += watcher_Changed;
|
||||
|
||||
newWatcher.Error += watcher_Error;
|
||||
|
||||
try
|
||||
{
|
||||
var newWatcher = new FileSystemWatcher(path, "*")
|
||||
{
|
||||
IncludeSubdirectories = true,
|
||||
InternalBufferSize = 32767
|
||||
};
|
||||
|
||||
newWatcher.NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.DirectoryName |
|
||||
NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.Size;
|
||||
|
||||
newWatcher.Created += watcher_Changed;
|
||||
newWatcher.Deleted += watcher_Changed;
|
||||
newWatcher.Renamed += watcher_Changed;
|
||||
newWatcher.Changed += watcher_Changed;
|
||||
|
||||
newWatcher.Error += watcher_Error;
|
||||
|
||||
if (_fileSystemWatchers.TryAdd(path, newWatcher))
|
||||
{
|
||||
newWatcher.EnableRaisingEvents = true;
|
||||
@ -272,11 +279,7 @@ namespace MediaBrowser.Server.Implementations.IO
|
||||
}
|
||||
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Logger.ErrorException("Error watching path: {0}", ex, path);
|
||||
}
|
||||
catch (PlatformNotSupportedException ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.ErrorException("Error watching path: {0}", ex, path);
|
||||
}
|
||||
@ -346,7 +349,9 @@ namespace MediaBrowser.Server.Implementations.IO
|
||||
{
|
||||
try
|
||||
{
|
||||
OnWatcherChanged(e);
|
||||
Logger.Debug("Watcher sees change of type " + e.ChangeType + " to " + e.FullPath);
|
||||
|
||||
ReportFileSystemChanged(e.FullPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -354,13 +359,6 @@ namespace MediaBrowser.Server.Implementations.IO
|
||||
}
|
||||
}
|
||||
|
||||
private void OnWatcherChanged(FileSystemEventArgs e)
|
||||
{
|
||||
Logger.Debug("Watcher sees change of type " + e.ChangeType + " to " + e.FullPath);
|
||||
|
||||
ReportFileSystemChanged(e.FullPath);
|
||||
}
|
||||
|
||||
public void ReportFileSystemChanged(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
@ -370,12 +368,9 @@ namespace MediaBrowser.Server.Implementations.IO
|
||||
|
||||
var filename = Path.GetFileName(path);
|
||||
|
||||
// Ignore certain files
|
||||
if (!string.IsNullOrEmpty(filename) && _alwaysIgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var monitorPath = !(!string.IsNullOrEmpty(filename) && _alwaysIgnoreFiles.Contains(filename, StringComparer.OrdinalIgnoreCase));
|
||||
|
||||
// Ignore certain files
|
||||
var tempIgnorePaths = _tempIgnoredPaths.Keys.ToList();
|
||||
|
||||
// If the parent of an ignored path has a change event, ignore that too
|
||||
@ -416,12 +411,15 @@ namespace MediaBrowser.Server.Implementations.IO
|
||||
|
||||
}))
|
||||
{
|
||||
return;
|
||||
monitorPath = false;
|
||||
}
|
||||
|
||||
// Avoid implicitly captured closure
|
||||
var affectedPath = path;
|
||||
_affectedPaths.AddOrUpdate(path, path, (key, oldValue) => affectedPath);
|
||||
if (monitorPath)
|
||||
{
|
||||
// Avoid implicitly captured closure
|
||||
var affectedPath = path;
|
||||
_affectedPaths.AddOrUpdate(path, path, (key, oldValue) => affectedPath);
|
||||
}
|
||||
|
||||
lock (_timerLock)
|
||||
{
|
||||
|
@ -48,14 +48,6 @@
|
||||
<Reference Include="Alchemy">
|
||||
<HintPath>..\packages\Alchemy.2.2.1\lib\net40\Alchemy.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="BDInfo, Version=1.0.5167.21152, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\BDInfo.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="DvdLib, Version=1.0.5167.21152, Culture=neutral, PublicKeyToken=7a2f3f5ec8d93575, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\DvdLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Mono.Nat, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\Mono.Nat.1.2.3\lib\Net40\Mono.Nat.dll</HintPath>
|
||||
@ -105,7 +97,6 @@
|
||||
<Compile Include="..\SharedVersion.cs">
|
||||
<Link>Properties\SharedVersion.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="BdInfo\BdInfoExaminer.cs" />
|
||||
<Compile Include="Channels\ChannelImageProvider.cs" />
|
||||
<Compile Include="Channels\ChannelItemImageProvider.cs" />
|
||||
<Compile Include="Channels\ChannelManager.cs" />
|
||||
@ -191,7 +182,6 @@
|
||||
<Compile Include="LiveTv\RefreshChannelsScheduledTask.cs" />
|
||||
<Compile Include="Localization\LocalizationManager.cs" />
|
||||
<Compile Include="MediaEncoder\EncodingManager.cs" />
|
||||
<Compile Include="MediaEncoder\MediaEncoder.cs" />
|
||||
<Compile Include="News\NewsEntryPoint.cs" />
|
||||
<Compile Include="News\NewsService.cs" />
|
||||
<Compile Include="Persistence\SqliteChapterRepository.cs" />
|
||||
|
@ -178,7 +178,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
|
||||
using (var stream = await _encoder.ExtractImage(inputPath, type, false, video.Video3DFormat, time, cancellationToken).ConfigureAwait(false))
|
||||
using (var stream = await _encoder.ExtractVideoImage(inputPath, type, video.Video3DFormat, time, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
using (var fileStream = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true))
|
||||
{
|
||||
|
@ -37,6 +37,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||
var createTableCommand
|
||||
= "create table if not exists mediastreams ";
|
||||
|
||||
// Add PixelFormat column
|
||||
|
||||
createTableCommand += "(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, PRIMARY KEY (ItemId, StreamIndex))";
|
||||
|
||||
string[] queries = {
|
||||
|
@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Alchemy" version="2.2.1" targetFramework="net45" />
|
||||
<package id="MediaBrowser.BdInfo" version="1.0.0.10" targetFramework="net45" />
|
||||
<package id="Mono.Nat" version="1.2.3" targetFramework="net45" />
|
||||
<package id="morelinq" version="1.0.16006" targetFramework="net45" />
|
||||
<package id="System.Data.SQLite.Core" version="1.0.91.3" targetFramework="net45" />
|
||||
|
@ -33,13 +33,14 @@ using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Controller.Themes;
|
||||
using MediaBrowser.Dlna;
|
||||
using MediaBrowser.Dlna.PlayTo;
|
||||
using MediaBrowser.MediaEncoding.BdInfo;
|
||||
using MediaBrowser.MediaEncoding.Encoder;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.MediaInfo;
|
||||
using MediaBrowser.Model.System;
|
||||
using MediaBrowser.Model.Updates;
|
||||
using MediaBrowser.Providers.Manager;
|
||||
using MediaBrowser.Server.Implementations;
|
||||
using MediaBrowser.Server.Implementations.BdInfo;
|
||||
using MediaBrowser.Server.Implementations.Channels;
|
||||
using MediaBrowser.Server.Implementations.Collections;
|
||||
using MediaBrowser.Server.Implementations.Configuration;
|
||||
@ -821,7 +822,10 @@ namespace MediaBrowser.ServerApplication
|
||||
// Server implementations
|
||||
list.Add(typeof(ServerApplicationPaths).Assembly);
|
||||
|
||||
// Dlna implementations
|
||||
// MediaEncoding
|
||||
list.Add(typeof(MediaEncoder).Assembly);
|
||||
|
||||
// Dlna
|
||||
list.Add(typeof(PlayToServerEntryPoint).Assembly);
|
||||
|
||||
list.AddRange(Assemblies.GetAssembliesWithParts());
|
||||
|
@ -195,6 +195,10 @@
|
||||
<Project>{734098eb-6dc1-4dd0-a1ca-3140dcd2737c}</Project>
|
||||
<Name>MediaBrowser.Dlna</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj">
|
||||
<Project>{0bd82fa6-eb8a-4452-8af5-74f9c3849451}</Project>
|
||||
<Name>MediaBrowser.MediaEncoding</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
|
||||
<Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
|
||||
<Name>MediaBrowser.Model</Name>
|
||||
|
@ -41,6 +41,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.ServerApplicat
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Dlna", "MediaBrowser.Dlna\MediaBrowser.Dlna.csproj", "{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.MediaEncoding", "MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj", "{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -247,6 +249,20 @@ Global
|
||||
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
Loading…
Reference in New Issue
Block a user