@ -1,9 +1,10 @@
using MediaBrowser.Controller.Channels ;
using System.IO ;
using MediaBrowser.Controller.Entities ;
using MediaBrowser.Controller.Library ;
using MediaBrowser.Controller.LiveTv ;
using MediaBrowser.Controller.MediaEncoding ;
using MediaBrowser.Model.Dlna ;
using MediaBrowser.Model.Dto ;
using MediaBrowser.Model.Entities ;
using MediaBrowser.Model.Logging ;
using MediaBrowser.Model.MediaInfo ;
@ -19,19 +20,15 @@ namespace MediaBrowser.MediaEncoding.Encoder
public class EncodingJobFactory
{
private readonly ILogger _logger ;
private readonly ILiveTvManager _liveTvManager ;
private readonly ILibraryManager _libraryManager ;
private readonly IChannelManager _channelManager ;
private readonly IMediaSourceManager _mediaSourceManager ;
protected static readonly CultureInfo UsCulture = new CultureInfo ( "en-US" ) ;
public EncodingJobFactory ( ILogger logger , ILi veTvManager liveTvManager , ILi braryManager library Manager, IChannelManager channel Manager, IMediaSourceManager mediaSourceManager )
public EncodingJobFactory ( ILogger logger , ILi braryManager library Manager, IMediaSourceManager mediaSourceManager )
{
_logger = logger ;
_liveTvManager = liveTvManager ;
_libraryManager = libraryManager ;
_channelManager = channelManager ;
_mediaSourceManager = mediaSourceManager ;
}
@ -42,9 +39,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
if ( string . IsNullOrEmpty ( request . AudioCodec ) )
{
request . AudioCodec = InferAudioCodec ( request . OutputContainer ) ;
}
var state = new EncodingJob ( _logger , _ liveTv Manager)
}
var state = new EncodingJob ( _logger , _ mediaSource Manager)
{
Options = options ,
IsVideoRequest = isVideoRequest ,
@ -58,106 +55,17 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
var item = _libraryManager . GetItemById ( request . ItemId ) ;
List < MediaStream > mediaStreams = null ;
state . ItemType = item . GetType ( ) . Name ;
if ( item is ILiveTvRecording )
{
var recording = await _liveTvManager . GetInternalRecording ( request . ItemId , cancellationToken ) . ConfigureAwait ( false ) ;
state . VideoType = VideoType . VideoFile ;
state . IsInputVideo = string . Equals ( recording . MediaType , MediaType . Video , StringComparison . OrdinalIgnoreCase ) ;
var path = recording . RecordingInfo . Path ;
var mediaUrl = recording . RecordingInfo . Url ;
var source = string . IsNullOrEmpty ( request . MediaSourceId )
? recording . GetMediaSources ( false ) . First ( )
: _mediaSourceManager . GetStaticMediaSource ( recording , request . MediaSourceId , false ) ;
mediaStreams = source . MediaStreams ;
// Just to prevent this from being null and causing other methods to fail
state . MediaPath = string . Empty ;
if ( ! string . IsNullOrEmpty ( path ) )
{
state . MediaPath = path ;
state . InputProtocol = MediaProtocol . File ;
}
else if ( ! string . IsNullOrEmpty ( mediaUrl ) )
{
state . MediaPath = mediaUrl ;
state . InputProtocol = MediaProtocol . Http ;
}
state . RunTimeTicks = recording . RunTimeTicks ;
state . DeInterlace = true ;
state . OutputAudioSync = "1000" ;
state . InputVideoSync = "-1" ;
state . InputAudioSync = "1" ;
state . InputContainer = recording . Container ;
state . ReadInputAtNativeFramerate = source . ReadAtNativeFramerate ;
}
else if ( item is LiveTvChannel )
{
var channel = _liveTvManager . GetInternalChannel ( request . ItemId ) ;
state . VideoType = VideoType . VideoFile ;
state . IsInputVideo = string . Equals ( channel . MediaType , MediaType . Video , StringComparison . OrdinalIgnoreCase ) ;
mediaStreams = new List < MediaStream > ( ) ;
state . DeInterlace = true ;
// Just to prevent this from being null and causing other methods to fail
state . MediaPath = string . Empty ;
}
else
{
var mediaSources = await _mediaSourceManager . GetPlayackMediaSources ( request . ItemId , false , cancellationToken ) . ConfigureAwait ( false ) ;
state . IsInputVideo = string . Equals ( item . MediaType , MediaType . Video , StringComparison . OrdinalIgnoreCase ) ;
var mediaSource = string . IsNullOrEmpty ( request . MediaSourceId )
? mediaSources . First ( )
: mediaSources . First ( i = > string . Equals ( i . Id , request . MediaSourceId ) ) ;
mediaStreams = mediaSource . MediaStreams ;
state . MediaPath = mediaSource . Path ;
state . InputProtocol = mediaSource . Protocol ;
state . InputContainer = mediaSource . Container ;
state . InputFileSize = mediaSource . Size ;
state . InputBitrate = mediaSource . Bitrate ;
state . ReadInputAtNativeFramerate = mediaSource . ReadAtNativeFramerate ;
state . RunTimeTicks = mediaSource . RunTimeTicks ;
state . RemoteHttpHeaders = mediaSource . RequiredHttpHeaders ;
var video = item as Video ;
if ( video ! = null )
{
state . IsInputVideo = true ;
if ( mediaSource . VideoType . HasValue )
{
state . VideoType = mediaSource . VideoType . Value ;
}
var mediaSources = await _mediaSourceManager . GetPlayackMediaSources ( request . ItemId , false , cancellationToken ) . ConfigureAwait ( false ) ;
state . IsoType = mediaSource . IsoType ;
var mediaSource = string . IsNullOrEmpty ( request . MediaSourceId )
? mediaSources . First ( )
: mediaSources . First ( i = > string . Equals ( i . Id , request . MediaSourceId ) ) ;
state . PlayableStreamFileNames = mediaSource . PlayableStreamFileNames . ToList ( ) ;
if ( mediaSource . Timestamp . HasValue )
{
state . InputTimestamp = mediaSource . Timestamp . Value ;
}
}
state . RunTimeTicks = mediaSource . RunTimeTicks ;
}
AttachMediaStreamInfo ( state , mediaStreams , request ) ;
AttachMediaStreamInfo ( state , mediaSource , options ) ;
state . OutputAudioBitrate = GetAudioBitrateParam ( request , state . AudioStream ) ;
state . OutputAudioSampleRate = request . AudioSampleRate ;
@ -185,26 +93,73 @@ namespace MediaBrowser.MediaEncoding.Encoder
ApplyDeviceProfileSettings ( state ) ;
if ( isVideoRequest )
TryStreamCopy ( state , request ) ;
return state ;
}
internal static void TryStreamCopy ( EncodingJob state ,
EncodingJobOptions videoRequest )
{
if ( state . IsVideoRequest )
{
if ( state . VideoStream ! = null & & CanStreamCopyVideo ( request , state . VideoStream ) )
if ( state . VideoStream ! = null & & CanStreamCopyVideo ( videoR equest, state . VideoStream ) )
{
state . OutputVideoCodec = "copy" ;
}
if ( state . AudioStream ! = null & & CanStreamCopyAudio ( request , state . AudioStream , state . SupportedAudioCodecs ) )
if ( state . AudioStream ! = null & & CanStreamCopyAudio ( videoR equest, state . AudioStream , state . SupportedAudioCodecs ) )
{
state . OutputAudioCodec = "copy" ;
}
}
return state ;
}
internal static void AttachMediaStreamInfo ( EncodingJob state ,
List< MediaStream > mediaStreams ,
MediaSourceInfo mediaSource ,
EncodingJobOptions videoRequest )
{
state . MediaPath = mediaSource . Path ;
state . InputProtocol = mediaSource . Protocol ;
state . InputContainer = mediaSource . Container ;
state . InputFileSize = mediaSource . Size ;
state . InputBitrate = mediaSource . Bitrate ;
state . ReadInputAtNativeFramerate = mediaSource . ReadAtNativeFramerate ;
state . RunTimeTicks = mediaSource . RunTimeTicks ;
state . RemoteHttpHeaders = mediaSource . RequiredHttpHeaders ;
if ( mediaSource . VideoType . HasValue )
{
state . VideoType = mediaSource . VideoType . Value ;
}
state . IsoType = mediaSource . IsoType ;
state . PlayableStreamFileNames = mediaSource . PlayableStreamFileNames . ToList ( ) ;
if ( mediaSource . Timestamp . HasValue )
{
state . InputTimestamp = mediaSource . Timestamp . Value ;
}
state . InputProtocol = mediaSource . Protocol ;
state . MediaPath = mediaSource . Path ;
state . RunTimeTicks = mediaSource . RunTimeTicks ;
state . RemoteHttpHeaders = mediaSource . RequiredHttpHeaders ;
state . InputBitrate = mediaSource . Bitrate ;
state . InputFileSize = mediaSource . Size ;
state . ReadInputAtNativeFramerate = mediaSource . ReadAtNativeFramerate ;
if ( state . ReadInputAtNativeFramerate | |
mediaSource . Protocol = = MediaProtocol . File & & string . Equals ( mediaSource . Container , "wtv" , StringComparison . OrdinalIgnoreCase ) )
{
state . OutputAudioSync = "1000" ;
state . InputVideoSync = "-1" ;
state . InputAudioSync = "1" ;
}
var mediaStreams = mediaSource . MediaStreams ;
if ( videoRequest ! = null )
{
if ( string . IsNullOrEmpty ( videoRequest . VideoCodec ) )
@ -233,7 +188,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
state . AudioStream = GetMediaStream ( mediaStreams , null , MediaStreamType . Audio , true ) ;
}
state . AllMediaStreams = mediaStreams ;
state . MediaSource = mediaSource ;
}
/// <summary>
@ -771,7 +726,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
state . TargetTimestamp ,
state . IsTargetAnamorphic ,
state . IsTargetCabac ,
state . TargetRefFrames ) ;
state . TargetRefFrames ,
state . TargetVideoStreamCount ,
state . TargetAudioStreamCount ) ;
if ( mediaProfile ! = null )
{