@ -13,6 +13,7 @@ using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Dto ;
using MediaBrowser.Model.Entities ;
using MediaBrowser.Model.IO ;
using MediaBrowser.Model.LiveTv ;
using System ;
using System.Collections.Generic ;
using System.Diagnostics ;
@ -539,8 +540,8 @@ namespace MediaBrowser.Api.Playback
/// <returns>System.String.</returns>
protected string GetProbeSizeArgument ( string mediaPath , bool isVideo , VideoType ? videoType , IsoType ? isoType )
{
var type = ! isVideo ? MediaEncoderHelpers . GetInputType ( mediaPath , null , null ) :
MediaEncoderHelpers . GetInputType ( mediaPath, videoType, isoType ) ;
var type = ! isVideo ? MediaEncoderHelpers . GetInputType ( null , null ) :
MediaEncoderHelpers . GetInputType ( videoType, isoType ) ;
return MediaEncoder . GetProbeSizeArgument ( type ) ;
}
@ -654,6 +655,11 @@ namespace MediaBrowser.Api.Playback
/// <returns>System.String.</returns>
protected string GetInputArgument ( StreamState state )
{
if ( state . SendInputOverStandardInput )
{
return "-" ;
}
var type = InputType . AudioFile ;
var inputPath = new [ ] { state . MediaPath } ;
@ -705,7 +711,9 @@ namespace MediaBrowser.Api.Playback
Arguments = GetCommandLineArguments ( outputPath , state , true ) ,
WindowStyle = ProcessWindowStyle . Hidden ,
ErrorDialog = false
ErrorDialog = false ,
RedirectStandardInput = state . SendInputOverStandardInput
} ,
EnableRaisingEvents = true
@ -738,6 +746,11 @@ namespace MediaBrowser.Api.Playback
throw ;
}
if ( state . SendInputOverStandardInput )
{
StreamToStandardInput ( process , state ) ;
}
// MUST read both stdout and stderr asynchronously or a deadlock may occurr
process . BeginOutputReadLine ( ) ;
@ -763,6 +776,34 @@ namespace MediaBrowser.Api.Playback
}
}
private async void StreamToStandardInput ( Process process , StreamState state )
{
state . StandardInputCancellationTokenSource = new CancellationTokenSource ( ) ;
try
{
await StreamToStandardInputInternal ( process , state ) . ConfigureAwait ( false ) ;
}
catch ( OperationCanceledException )
{
Logger . Debug ( "Stream to standard input closed normally." ) ;
}
catch ( Exception ex )
{
Logger . ErrorException ( "Error writing to standard input" , ex ) ;
}
}
private async Task StreamToStandardInputInternal ( Process process , StreamState state )
{
state . StandardInputCancellationTokenSource = new CancellationTokenSource ( ) ;
using ( var fileStream = FileSystem . GetFileStream ( state . MediaPath , FileMode . Open , FileAccess . Read , FileShare . ReadWrite , true ) )
{
await new EndlessStreamCopy ( ) . CopyStream ( fileStream , process . StandardInput . BaseStream , state . StandardInputCancellationTokenSource . Token ) . ConfigureAwait ( false ) ;
}
}
protected int? GetVideoBitrateParam ( StreamState state )
{
return state . VideoRequest . VideoBitRate ;
@ -831,6 +872,11 @@ namespace MediaBrowser.Api.Playback
state . IsoMount = null ;
}
if ( state . StandardInputCancellationTokenSource ! = null )
{
state . StandardInputCancellationTokenSource . Cancel ( ) ;
}
var outputFilePath = GetOutputFilePath ( state ) ;
state . LogFileStream . Dispose ( ) ;
@ -903,10 +949,11 @@ namespace MediaBrowser.Api.Playback
}
itemId = recording . Id ;
state . SendInputOverStandardInput = recording . RecordingInfo . Status = = RecordingStatus . InProgress ;
}
else if ( string . Equals ( request . Type , "Channel" , StringComparison . OrdinalIgnoreCase ) )
{
var channel = LiveTvManager . GetInternalChannel ( request . Id ) ;
var channel = LiveTvManager . GetInternalChannel ( request . Id ) ;
state . VideoType = VideoType . VideoFile ;
state . IsInputVideo = string . Equals ( channel . MediaType , MediaType . Video , StringComparison . OrdinalIgnoreCase ) ;
@ -926,6 +973,7 @@ namespace MediaBrowser.Api.Playback
}
itemId = channel . Id ;
state . SendInputOverStandardInput = true ;
}
else
{