aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Api/Playback
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Api/Playback')
-rw-r--r--MediaBrowser.Api/Playback/Hls/BaseHlsService.cs44
-rw-r--r--MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs7
-rw-r--r--MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs23
-rw-r--r--MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs4
-rw-r--r--MediaBrowser.Api/Playback/StreamState.cs10
5 files changed, 60 insertions, 28 deletions
diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
index 761b1eb4e..319e4bbb6 100644
--- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
@@ -87,7 +87,8 @@ namespace MediaBrowser.Api.Playback.Hls
if (!FileSystem.FileExists(playlist))
{
- await ApiEntryPoint.Instance.TranscodingStartLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false);
+ var transcodingLock = ApiEntryPoint.Instance.GetTranscodingLock(playlist);
+ await transcodingLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false);
try
{
if (!FileSystem.FileExists(playlist))
@@ -104,13 +105,13 @@ namespace MediaBrowser.Api.Playback.Hls
throw;
}
- var waitForSegments = state.SegmentLength >= 10 ? 2 : (state.SegmentLength > 3 || !isLive ? 3 : 4);
+ var waitForSegments = state.SegmentLength >= 10 ? 2 : (state.SegmentLength > 3 || !isLive ? 3 : 3);
await WaitForMinimumSegmentCount(playlist, waitForSegments, cancellationTokenSource.Token).ConfigureAwait(false);
}
}
finally
{
- ApiEntryPoint.Instance.TranscodingStartLock.Release();
+ transcodingLock.Release();
}
}
@@ -182,32 +183,41 @@ namespace MediaBrowser.Api.Playback.Hls
{
Logger.Debug("Waiting for {0} segments in {1}", segmentCount, playlist);
- while (true)
+ while (!cancellationToken.IsCancellationRequested)
{
- // Need to use FileShare.ReadWrite because we're reading the file at the same time it's being written
- using (var fileStream = GetPlaylistFileStream(playlist))
+ try
{
- using (var reader = new StreamReader(fileStream))
+ // Need to use FileShare.ReadWrite because we're reading the file at the same time it's being written
+ using (var fileStream = GetPlaylistFileStream(playlist))
{
- var count = 0;
-
- while (!reader.EndOfStream)
+ using (var reader = new StreamReader(fileStream))
{
- var line = await reader.ReadLineAsync().ConfigureAwait(false);
+ var count = 0;
- if (line.IndexOf("#EXTINF:", StringComparison.OrdinalIgnoreCase) != -1)
+ while (!reader.EndOfStream)
{
- count++;
- if (count >= segmentCount)
+ var line = await reader.ReadLineAsync().ConfigureAwait(false);
+
+ if (line.IndexOf("#EXTINF:", StringComparison.OrdinalIgnoreCase) != -1)
{
- Logger.Debug("Finished waiting for {0} segments in {1}", segmentCount, playlist);
- return;
+ count++;
+ if (count >= segmentCount)
+ {
+ Logger.Debug("Finished waiting for {0} segments in {1}", segmentCount, playlist);
+ return;
+ }
}
}
+ await Task.Delay(100, cancellationToken).ConfigureAwait(false);
}
- await Task.Delay(100, cancellationToken).ConfigureAwait(false);
}
}
+ catch (IOException)
+ {
+ // May get an error if the file is locked
+ }
+
+ await Task.Delay(50, cancellationToken).ConfigureAwait(false);
}
}
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index 9cd55528d..d4ddbd7c5 100644
--- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
@@ -171,14 +171,15 @@ namespace MediaBrowser.Api.Playback.Hls
return await GetSegmentResult(state, playlistPath, segmentPath, requestedIndex, job, cancellationToken).ConfigureAwait(false);
}
- await ApiEntryPoint.Instance.TranscodingStartLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false);
+ var transcodingLock = ApiEntryPoint.Instance.GetTranscodingLock(playlistPath);
+ await transcodingLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false);
var released = false;
try
{
if (FileSystem.FileExists(segmentPath))
{
job = ApiEntryPoint.Instance.OnTranscodeBeginRequest(playlistPath, TranscodingJobType);
- ApiEntryPoint.Instance.TranscodingStartLock.Release();
+ transcodingLock.Release();
released = true;
return await GetSegmentResult(state, playlistPath, segmentPath, requestedIndex, job, cancellationToken).ConfigureAwait(false);
}
@@ -242,7 +243,7 @@ namespace MediaBrowser.Api.Playback.Hls
{
if (!released)
{
- ApiEntryPoint.Instance.TranscodingStartLock.Release();
+ transcodingLock.Release();
}
}
diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
index b8cb6b14f..a68319109 100644
--- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
@@ -17,6 +17,7 @@ using System.IO;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using ServiceStack;
namespace MediaBrowser.Api.Playback.Progressive
{
@@ -129,6 +130,23 @@ namespace MediaBrowser.Api.Playback.Progressive
using (state)
{
+ if (state.MediaPath.IndexOf("/livestreamfiles/", StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ var parts = state.MediaPath.Split('/');
+ var filename = parts[parts.Length - 2] + Path.GetExtension(parts[parts.Length - 1]);
+ var filePath = Path.Combine(ServerConfigurationManager.ApplicationPaths.TranscodingTempPath, filename);
+
+ var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+
+ outputHeaders["Content-Type"] = MimeTypes.GetMimeType(filePath);
+
+ var streamSource = new ProgressiveFileCopier(FileSystem, filePath, outputHeaders, null, Logger, CancellationToken.None)
+ {
+ AllowEndOfFile = false
+ };
+ return ResultFactory.GetAsyncStreamWriter(streamSource);
+ }
+
return await GetStaticRemoteStreamResult(state, responseHeaders, isHeadRequest, cancellationTokenSource)
.ConfigureAwait(false);
}
@@ -345,7 +363,8 @@ namespace MediaBrowser.Api.Playback.Progressive
return streamResult;
}
- await ApiEntryPoint.Instance.TranscodingStartLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false);
+ var transcodingLock = ApiEntryPoint.Instance.GetTranscodingLock(outputPath);
+ await transcodingLock.WaitAsync(cancellationTokenSource.Token).ConfigureAwait(false);
try
{
TranscodingJob job;
@@ -376,7 +395,7 @@ namespace MediaBrowser.Api.Playback.Progressive
}
finally
{
- ApiEntryPoint.Instance.TranscodingStartLock.Release();
+ transcodingLock.Release();
}
}
diff --git a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs
index 0a9a44641..80b5e357d 100644
--- a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs
+++ b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs
@@ -24,6 +24,8 @@ namespace MediaBrowser.Api.Playback.Progressive
private long _bytesWritten = 0;
+ public bool AllowEndOfFile = true;
+
public ProgressiveFileCopier(IFileSystem fileSystem, string path, Dictionary<string, string> outputHeaders, TranscodingJob job, ILogger logger, CancellationToken cancellationToken)
{
_fileSystem = fileSystem;
@@ -50,7 +52,7 @@ namespace MediaBrowser.Api.Playback.Progressive
using (var fs = _fileSystem.GetFileStream(_path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true))
{
- while (eofCount < 15)
+ while (eofCount < 15 || !AllowEndOfFile)
{
var bytesRead = await CopyToAsyncInternal(fs, outputStream, BufferSize, _cancellationToken).ConfigureAwait(false);
diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs
index 109aa85de..ef0282abc 100644
--- a/MediaBrowser.Api/Playback/StreamState.cs
+++ b/MediaBrowser.Api/Playback/StreamState.cs
@@ -73,10 +73,6 @@ namespace MediaBrowser.Api.Playback
{
get
{
- if (!RunTimeTicks.HasValue)
- {
- return 6;
- }
if (string.Equals(OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
{
var userAgent = UserAgent ?? string.Empty;
@@ -92,12 +88,16 @@ namespace MediaBrowser.Api.Playback
return 10;
}
+ if (!RunTimeTicks.HasValue)
+ {
+ return 3;
+ }
return 6;
}
if (!RunTimeTicks.HasValue)
{
- return 6;
+ return 3;
}
return 3;
}