@ -2215,13 +2215,13 @@ namespace MediaBrowser.Controller.MediaEncoding
return state . IsInputVideo ? "-sn" : string . Empty ;
}
// We have media info, but we don't know the stream index es
// We have media info, but we don't know the stream index
if ( state . VideoStream ! = null & & state . VideoStream . Index = = - 1 )
{
return "-sn" ;
}
// We have media info, but we don't know the stream index es
// We have media info, but we don't know the stream index
if ( state . AudioStream ! = null & & state . AudioStream . Index = = - 1 )
{
return state . IsInputVideo ? "-sn" : string . Empty ;
@ -2231,10 +2231,12 @@ namespace MediaBrowser.Controller.MediaEncoding
if ( state . VideoStream ! = null )
{
int videoStreamIndex = FindIndex ( state . MediaSource . MediaStreams , state . VideoStream ) ;
args + = string . Format (
CultureInfo . InvariantCulture ,
"-map 0:{0}" ,
state. VideoStream . Index) ;
videoStream Index) ;
}
else
{
@ -2244,24 +2246,24 @@ namespace MediaBrowser.Controller.MediaEncoding
if ( state . AudioStream ! = null )
{
int audioStreamIndex = FindIndex ( state . MediaSource . MediaStreams , state . AudioStream ) ;
if ( state . AudioStream . IsExternal )
{
bool hasExternalGraphicsSubs = state . SubtitleStream ! = null & & state . SubtitleStream . IsExternal & & ! state . SubtitleStream . IsTextSubtitleStream ;
int externalAudioMapIndex = hasExternalGraphicsSubs ? 2 : 1 ;
int externalAudioStream = state . MediaSource . MediaStreams . Where ( i = > i . Path = = state . AudioStream . Path ) . ToList ( ) . IndexOf ( state . AudioStream ) ;
args + = string . Format (
CultureInfo . InvariantCulture ,
" -map {0}:{1}" ,
externalAudioMapIndex ,
extern alA udioStream) ;
audioStreamIndex ) ;
}
else
{
args + = string . Format (
CultureInfo . InvariantCulture ,
" -map 0:{0}" ,
st ate. A udioStream. Index) ;
audioStreamIndex) ;
}
}
else
@ -2276,14 +2278,21 @@ namespace MediaBrowser.Controller.MediaEncoding
}
else if ( subtitleMethod = = SubtitleDeliveryMethod . Embed )
{
int subtitleStreamIndex = FindIndex ( state . MediaSource . MediaStreams , state . SubtitleStream ) ;
args + = string . Format (
CultureInfo . InvariantCulture ,
" -map 0:{0}" ,
s tate. S ubtitleStream. Index) ;
s ubtitleStreamIndex) ;
}
else if ( state . SubtitleStream . IsExternal & & ! state . SubtitleStream . IsTextSubtitleStream )
{
args + = " -map 1:0 -sn" ;
int externalSubtitleStreamIndex = FindIndex ( state . MediaSource . MediaStreams , state . SubtitleStream ) ;
args + = string . Format (
CultureInfo . InvariantCulture ,
" -map 1:{0} -sn" ,
externalSubtitleStreamIndex ) ;
}
return args ;
@ -2512,7 +2521,7 @@ namespace MediaBrowser.Controller.MediaEncoding
return string . Format (
CultureInfo . InvariantCulture ,
"scale=trunc(min(max(iw\\,ih* d ar )\\,min({0}\\,{1}*d ar ))/{2})*{2}:trunc(min(max(iw/d ar \\,ih)\\,min({0}/d ar \\,{1}))/2)*2",
"scale=trunc(min(max(iw\\,ih* a)\\,min({0}\\,{1}*a))/{2})*{2}:trunc(min(max(iw/a\\,ih)\\,min({0}/a\\,{1}))/2)*2",
maxWidthParam ,
maxHeightParam ,
scaleVal ) ;
@ -2556,7 +2565,7 @@ namespace MediaBrowser.Controller.MediaEncoding
return string . Format (
CultureInfo . InvariantCulture ,
"scale=trunc(min(max(iw\\,ih* d ar )\\,{0})/{1})*{1}:trunc(ow/d ar /2)*2",
"scale=trunc(min(max(iw\\,ih* a)\\,{0})/{1})*{1}:trunc(ow/a/2)*2",
maxWidthParam ,
scaleVal ) ;
}
@ -2568,7 +2577,7 @@ namespace MediaBrowser.Controller.MediaEncoding
return string . Format (
CultureInfo . InvariantCulture ,
"scale=trunc(oh*a/{1})*{1}:min(max(iw/ d ar \\,ih)\\,{0})",
"scale=trunc(oh*a/{1})*{1}:min(max(iw/ a\\,ih)\\,{0})",
maxHeightParam ,
scaleVal ) ;
}
@ -2617,7 +2626,7 @@ namespace MediaBrowser.Controller.MediaEncoding
}
else
{
filter = "scale={0}:trunc({0}/ d ar /2)*2";
filter = "scale={0}:trunc({0}/ a/2)*2";
}
}
@ -2771,8 +2780,8 @@ namespace MediaBrowser.Controller.MediaEncoding
}
else if ( hasGraphicalSubs )
{
// [0:s]scale= s=1280x720
var subSwScaleFilter = Get Custom SwScaleFilter( inW, inH , reqW , reqH , reqMaxW , reqMaxH ) ;
// [0:s]scale= expr
var subSwScaleFilter = Get SwScaleFilter( state, options , vidEncoder , inW, inH , threeDFormat , reqW , reqH , reqMaxW , reqMaxH ) ;
subFilters . Add ( subSwScaleFilter ) ;
overlayFilters . Add ( "overlay=eof_action=endall:shortest=1:repeatlast=0" ) ;
}
@ -2958,7 +2967,9 @@ namespace MediaBrowser.Controller.MediaEncoding
{
if ( hasGraphicalSubs )
{
var subSwScaleFilter = GetCustomSwScaleFilter ( inW , inH , reqW , reqH , reqMaxW , reqMaxH ) ;
var subSwScaleFilter = isSwDecoder
? GetSwScaleFilter ( state , options , vidEncoder , inW , inH , threeDFormat , reqW , reqH , reqMaxW , reqMaxH )
: GetCustomSwScaleFilter ( inW , inH , reqW , reqH , reqMaxW , reqMaxH ) ;
subFilters . Add ( subSwScaleFilter ) ;
overlayFilters . Add ( "overlay=eof_action=endall:shortest=1:repeatlast=0" ) ;
}
@ -3156,7 +3167,9 @@ namespace MediaBrowser.Controller.MediaEncoding
{
if ( hasGraphicalSubs )
{
var subSwScaleFilter = GetCustomSwScaleFilter ( inW , inH , reqW , reqH , reqMaxW , reqMaxH ) ;
var subSwScaleFilter = isSwDecoder
? GetSwScaleFilter ( state , options , vidEncoder , inW , inH , threeDFormat , reqW , reqH , reqMaxW , reqMaxH )
: GetCustomSwScaleFilter ( inW , inH , reqW , reqH , reqMaxW , reqMaxH ) ;
subFilters . Add ( subSwScaleFilter ) ;
overlayFilters . Add ( "overlay=eof_action=endall:shortest=1:repeatlast=0" ) ;
}
@ -3402,7 +3415,9 @@ namespace MediaBrowser.Controller.MediaEncoding
{
if ( hasGraphicalSubs )
{
var subSwScaleFilter = GetCustomSwScaleFilter ( inW , inH , reqW , reqH , reqMaxW , reqMaxH ) ;
var subSwScaleFilter = isSwDecoder
? GetSwScaleFilter ( state , options , vidEncoder , inW , inH , threeDFormat , reqW , reqH , reqMaxW , reqMaxH )
: GetCustomSwScaleFilter ( inW , inH , reqW , reqH , reqMaxW , reqMaxH ) ;
subFilters . Add ( subSwScaleFilter ) ;
overlayFilters . Add ( "overlay=eof_action=endall:shortest=1:repeatlast=0" ) ;
}
@ -3611,7 +3626,9 @@ namespace MediaBrowser.Controller.MediaEncoding
{
if ( hasGraphicalSubs )
{
var subSwScaleFilter = GetCustomSwScaleFilter ( inW , inH , reqW , reqH , reqMaxW , reqMaxH ) ;
var subSwScaleFilter = isSwDecoder
? GetSwScaleFilter ( state , options , vidEncoder , inW , inH , threeDFormat , reqW , reqH , reqMaxW , reqMaxH )
: GetCustomSwScaleFilter ( inW , inH , reqW , reqH , reqMaxW , reqMaxH ) ;
subFilters . Add ( subSwScaleFilter ) ;
overlayFilters . Add ( "overlay=eof_action=pass:shortest=1:repeatlast=0" ) ;
}
@ -3858,7 +3875,9 @@ namespace MediaBrowser.Controller.MediaEncoding
{
if ( hasGraphicalSubs )
{
var subSwScaleFilter = GetCustomSwScaleFilter ( inW , inH , reqW , reqH , reqMaxW , reqMaxH ) ;
var subSwScaleFilter = isSwDecoder
? GetSwScaleFilter ( state , options , vidEncoder , inW , inH , threeDFormat , reqW , reqH , reqMaxW , reqMaxH )
: GetCustomSwScaleFilter ( inW , inH , reqW , reqH , reqMaxW , reqMaxH ) ;
subFilters . Add ( subSwScaleFilter ) ;
overlayFilters . Add ( "overlay=eof_action=pass:shortest=1:repeatlast=0" ) ;
@ -4033,7 +4052,9 @@ namespace MediaBrowser.Controller.MediaEncoding
{
if ( hasGraphicalSubs )
{
var subSwScaleFilter = GetCustomSwScaleFilter ( inW , inH , reqW , reqH , reqMaxW , reqMaxH ) ;
var subSwScaleFilter = isSwDecoder
? GetSwScaleFilter ( state , options , vidEncoder , inW , inH , threeDFormat , reqW , reqH , reqMaxW , reqMaxH )
: GetCustomSwScaleFilter ( inW , inH , reqW , reqH , reqMaxW , reqMaxH ) ;
subFilters . Add ( subSwScaleFilter ) ;
overlayFilters . Add ( "overlay=eof_action=pass:shortest=1:repeatlast=0" ) ;
@ -4129,9 +4150,8 @@ namespace MediaBrowser.Controller.MediaEncoding
string . Join ( ',' , overlayFilters ) ) ;
var mapPrefix = Convert . ToInt32 ( state . SubtitleStream . IsExternal ) ;
var subtitleStreamIndex = state . SubtitleStream . IsExternal
? 0
: state . SubtitleStream . Index ;
var subtitleStreamIndex = FindIndex ( state . MediaSource . MediaStreams , state . SubtitleStream ) ;
var videoStreamIndex = FindIndex ( state . MediaSource . MediaStreams , state . VideoStream ) ;
if ( hasSubs )
{
@ -4152,7 +4172,7 @@ namespace MediaBrowser.Controller.MediaEncoding
filterStr ,
mapPrefix ,
subtitleStreamIndex ,
state. VideoStream . Index,
videoStream Index,
mainStr ,
subStr ,
overlayStr ) ;
@ -5362,12 +5382,22 @@ namespace MediaBrowser.Controller.MediaEncoding
audioTranscodeParams . Add ( "-ac " + state . OutputAudioChannels . Value . ToString ( CultureInfo . InvariantCulture ) ) ;
}
// opus will fail on 44100
if ( ! string . Equals ( state . OutputAudioCodec , "opus" , StringComparison . OrdinalIgnoreCase ) )
{
if ( state . OutputAudioSampleRate . HasValue )
// opus only supports specific sampling rates
var sampleRate = state . OutputAudioSampleRate ;
if ( sampleRate . HasValue )
{
audioTranscodeParams . Add ( "-ar " + state . OutputAudioSampleRate . Value . ToString ( CultureInfo . InvariantCulture ) ) ;
var sampleRateValue = sampleRate . Value switch
{
< = 8000 = > 8000 ,
< = 12000 = > 12000 ,
< = 16000 = > 16000 ,
< = 24000 = > 24000 ,
_ = > 48000
} ;
audioTranscodeParams . Add ( "-ar " + sampleRateValue . ToString ( CultureInfo . InvariantCulture ) ) ;
}
}
@ -5389,6 +5419,28 @@ namespace MediaBrowser.Controller.MediaEncoding
string . Empty ) . Trim ( ) ;
}
public static int FindIndex ( IReadOnlyList < MediaStream > mediaStreams , MediaStream streamToFind )
{
var index = 0 ;
var length = mediaStreams . Count ;
for ( var i = 0 ; i < length ; i + + )
{
var currentMediaStream = mediaStreams [ i ] ;
if ( currentMediaStream = = streamToFind )
{
return index ;
}
if ( string . Equals ( currentMediaStream . Path , streamToFind . Path , StringComparison . Ordinal ) )
{
index + + ;
}
}
return - 1 ;
}
public static bool IsCopyCodec ( string codec )
{
return string . Equals ( codec , "copy" , StringComparison . OrdinalIgnoreCase ) ;