@ -101,9 +101,9 @@ namespace MediaBrowser.Api.Playback
/// </summary>
/// <param name="outputPath">The output path.</param>
/// <param name="state">The state.</param>
/// <param name=" performSubtitleConversions">if set to <c>true</c> [perform subtitle conversions ].</param>
/// <param name=" isEncoding">if set to <c>true</c> [is encoding ].</param>
/// <returns>System.String.</returns>
protected abstract string GetCommandLineArguments ( string outputPath , StreamState state , bool performSubtitleConversions ) ;
protected abstract string GetCommandLineArguments ( string outputPath , StreamState state , bool isEncoding ) ;
/// <summary>
/// Gets the type of the transcoding job.
@ -478,12 +478,10 @@ namespace MediaBrowser.Api.Playback
/// </summary>
/// <param name="state">The state.</param>
/// <param name="outputVideoCodec">The output video codec.</param>
/// <param name="performTextSubtitleConversion">if set to <c>true</c> [perform text subtitle conversion].</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>System.String.</returns>
protected string GetOutputSizeParam ( StreamState state ,
string outputVideoCodec ,
bool performTextSubtitleConversion ,
CancellationToken cancellationToken )
{
// http://sonnati.wordpress.com/2012/10/19/ffmpeg-the-swiss-army-knife-of-internet-streaming-part-vi/
@ -496,7 +494,7 @@ namespace MediaBrowser.Api.Playback
if ( state . SubtitleStream ! = null & & ! state . SubtitleStream . IsGraphicalSubtitleStream )
{
assSubtitleParam = GetTextSubtitleParam ( state , performTextSubtitleConversion, cancellationToken) ;
assSubtitleParam = GetTextSubtitleParam ( state , cancellationToken) ;
copyTsParam = " -copyts" ;
}
@ -574,103 +572,41 @@ namespace MediaBrowser.Api.Playback
/// Gets the text subtitle param.
/// </summary>
/// <param name="state">The state.</param>
/// <param name="performConversion">if set to <c>true</c> [perform conversion].</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>System.String.</returns>
protected string GetTextSubtitleParam ( StreamState state ,
bool performConversion ,
CancellationToken cancellationToken )
{
var path = state . SubtitleStream . IsExternal ?
GetConvertedAssPath ( state . SubtitleStream , performConversion , cancellationToken ) :
GetExtractedAssPath ( state , performConversion , cancellationToken ) ;
if ( string . IsNullOrEmpty ( path ) )
{
return string . Empty ;
}
var seconds = TimeSpan . FromTicks ( state . Request . StartTimeTicks ? ? 0 ) . TotalSeconds ;
return string . Format ( ",ass='{0}',setpts=PTS -{1}/TB" ,
path . Replace ( '\\' , '/' ) . Replace ( ":/" , "\\:/" ) ,
Math . Round ( seconds ) . ToString ( UsCulture ) ) ;
}
/// <summary>
/// Gets the extracted ass path.
/// </summary>
/// <param name="state">The state.</param>
/// <param name="performConversion">if set to <c>true</c> [perform conversion].</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>System.String.</returns>
private string GetExtractedAssPath ( StreamState state ,
bool performConversion ,
CancellationToken cancellationToken )
{
var path = EncodingManager . GetSubtitleCachePath ( state . MediaPath , state . SubtitleStream . Index , ".ass" ) ;
if ( performConversion )
if ( state . SubtitleStream . IsExternal )
{
InputType type ;
var subtitlePath = state . SubtitleStream . Path ;
var inputPath = MediaEncoderHelpers . GetInputArgument ( state . MediaPath , state . IsRemote , state . VideoType , state . IsoType , null , state . PlayableStreamFileNames , out type ) ;
var charsetParam = string . Empty ;
try
if ( ! string . IsNullOrEmpty ( state . SubtitleStream . Language ) )
{
var parentPath = Path . GetDirectoryName ( path ) ;
var charenc = MediaEncoder . GetSubtitleLanguageEncodingParam ( subtitlePath , state . SubtitleStream . Language ) ;
Directory . CreateDirectory ( parentPath ) ;
// Don't re-encode ass/ssa to ass because ffmpeg ass encoder fails if there's more than one ass rectangle. Affect Anime mostly.
// See https://lists.ffmpeg.org/pipermail/ffmpeg-cvslog/2013-April/063616.html
var isAssSubtitle = string . Equals ( state . SubtitleStream . Codec , "ass" , StringComparison . OrdinalIgnoreCase ) | | string . Equals ( state . SubtitleStream . Codec , "ssa" , StringComparison . OrdinalIgnoreCase ) ;
var task = MediaEncoder . ExtractTextSubtitle ( inputPath , type , state . SubtitleStream . Index , isAssSubtitle , path , cancellationToken ) ;
Task . WaitAll ( task ) ;
}
catch
{
return null ;
if ( ! string . IsNullOrEmpty ( charenc ) )
{
charsetParam = ":charenc=" + charenc ;
}
}
}
return path ;
}
/// <summary>
/// Gets the converted ass path.
/// </summary>
/// <param name="subtitleStream">The subtitle stream.</param>
/// <param name="performConversion">if set to <c>true</c> [perform conversion].</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>System.String.</returns>
private string GetConvertedAssPath ( MediaStream subtitleStream ,
bool performConversion ,
CancellationToken cancellationToken )
{
var path = EncodingManager . GetSubtitleCachePath ( subtitleStream . Path , ".ass" ) ;
// TODO: Perhaps also use original_size=1920x800
if ( performConversion )
{
try
{
var parentPath = Path . GetDirectoryName ( path ) ;
Directory . CreateDirectory ( parentPath ) ;
var task = MediaEncoder . ConvertTextSubtitleToAss ( subtitleStream . Path , path , subtitleStream . Language , cancellationToken ) ;
Task . WaitAll ( task ) ;
}
catch
{
return null ;
}
return string . Format ( ",subtitles=filename='{0}'{1},setpts=PTS -{2}/TB" ,
subtitlePath . Replace ( '\\' , '/' ) . Replace ( ":/" , "\\:/" ) ,
charsetParam ,
Math . Round ( seconds ) . ToString ( UsCulture ) ) ;
}
return path ;
return string . Format ( ",subtitles='{0}:si={1}',setpts=PTS -{2}/TB" ,
state . MediaPath . Replace ( '\\' , '/' ) . Replace ( ":/" , "\\:/" ) ,
state . SubtitleStream . Index . ToString ( UsCulture ) ,
Math . Round ( seconds ) . ToString ( UsCulture ) ) ;
}
/// <summary>
@ -688,7 +624,7 @@ namespace MediaBrowser.Api.Playback
// Add resolution params, if specified
if ( request . Width . HasValue | | request . Height . HasValue | | request . MaxHeight . HasValue | | request . MaxWidth . HasValue )
{
outputSizeParam = GetOutputSizeParam ( state , outputVideoCodec , false , CancellationToken . None ) . TrimEnd ( '"' ) ;
outputSizeParam = GetOutputSizeParam ( state , outputVideoCodec , CancellationToken . None ) . TrimEnd ( '"' ) ;
outputSizeParam = "," + outputSizeParam . Substring ( outputSizeParam . IndexOf ( "scale" , StringComparison . OrdinalIgnoreCase ) ) ;
}
@ -1585,7 +1521,7 @@ namespace MediaBrowser.Api.Playback
state . OutputAudioCodec = GetAudioCodec ( state . Request ) ;
state . OutputAudioChannels = GetNumAudioChannelsParam ( state . Request , state . AudioStream , state . OutputAudioCodec ) ;
if ( videoRequest ! = null )
{
state . OutputVideoCodec = GetVideoCodec ( videoRequest ) ;