Allowing the transmuxer to return a dash manifest before the end of the transmux.

This commit is contained in:
Zoe Roux 2019-11-12 23:11:11 +01:00
parent 4fa5a6b30f
commit a51204a1b3
8 changed files with 41 additions and 29 deletions

View File

@ -11,7 +11,7 @@
extern "C" API int Init();
extern "C" API int transmux(const char *path, const char *outPath);
extern "C" API int transmux(const char *path, const char *out_path, float *playable_duration);
//Take the path of the file and the path of the output directory. It will return the list of subtitle streams in the streams variable. The int returned is the number of subtitles extracted.
extern "C" API Stream* extract_subtitles(const char *path, const char *outPath, int *streamCount, int *subtitleCount);

View File

@ -8,7 +8,7 @@ int Init()
return sizeof(Stream);
}
int transmux(const char *path, const char *out_path)
int transmux(const char *path, const char *out_path, float *playable_duration)
{
AVFormatContext *in_ctx = NULL;
AVFormatContext *out_ctx = NULL;
@ -19,6 +19,7 @@ int transmux(const char *path, const char *out_path)
int stream_count;
int ret = 0;
*playable_duration = 0;
if (open_input_context(&in_ctx, path) != 0)
return 1;
@ -73,6 +74,8 @@ int transmux(const char *path, const char *out_path)
stream = in_ctx->streams[pkt.stream_index];
pkt.stream_index = stream_map[pkt.stream_index];
process_packet(pkt, stream, out_ctx->streams[pkt.stream_index]);
if (pkt.stream_index == 0)
*playable_duration += pkt.duration * (float)out_ctx->streams[pkt.stream_index]->time_base.num / out_ctx->streams[pkt.stream_index]->time_base.den;
if (av_interleaved_write_frame(out_ctx, &pkt) < 0)
std::cout << "Error while writing a packet to the output file." << std::endl;

7
Kyoo/.editorconfig Normal file
View File

@ -0,0 +1,7 @@
[*.cs]
# CS4014: Because this call is not awaited, execution of the current method continues before the call is completed
dotnet_diagnostic.CS4014.severity = silent
# IDE1006: Naming Styles
dotnet_diagnostic.IDE1006.severity = none

View File

@ -3,6 +3,7 @@ using Kyoo.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using System.IO;
using System.Threading.Tasks;
namespace Kyoo.Controllers
{
@ -33,13 +34,13 @@ namespace Kyoo.Controllers
}
[HttpGet("transmux/{showSlug}-s{seasonNumber}e{episodeNumber}/")]
public IActionResult Transmux(string showSlug, long seasonNumber, long episodeNumber)
public async Task<IActionResult> Transmux(string showSlug, long seasonNumber, long episodeNumber)
{
WatchItem episode = libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber);
if (episode != null && System.IO.File.Exists(episode.Path))
{
string path = transcoder.Transmux(episode);
string path = await transcoder.Transmux(episode);
if (path != null)
return PhysicalFile(path, "application/dash+xml", true);
else
@ -61,15 +62,16 @@ namespace Kyoo.Controllers
[HttpGet("transcode/{showSlug}-s{seasonNumber}e{episodeNumber}")]
public IActionResult Transcode(string showSlug, long seasonNumber, long episodeNumber)
{
WatchItem episode = libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber);
return null;
//WatchItem episode = libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber);
if (episode != null && System.IO.File.Exists(episode.Path))
{
string path = transcoder.Transcode(episode.Path);
return PhysicalFile(path, "video/mp4", true); //Should use mpeg dash
}
else
return NotFound();
//if (episode != null && System.IO.File.Exists(episode.Path))
//{
// string path = transcoder.Transcode(episode.Path);
// return PhysicalFile(path, "video/mp4", true); //Should use mpeg dash
//}
//else
// return NotFound();
}
}
}

View File

@ -1,8 +0,0 @@
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "C++ bindings", Scope = "member", Target = "~M:Kyoo.InternalAPI.TranscoderLink.TranscoderAPI.transmux(System.String,System.String)~System.Int32")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "C++ bindings", Scope = "member", Target = "~M:Kyoo.InternalAPI.TranscoderLink.TranscoderAPI.free_memory(System.IntPtr)")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "C++ bindings", Scope = "member", Target = "~M:Kyoo.InternalAPI.TranscoderLink.TranscoderAPI.extract_subtitles(System.String,System.String,System.Int32@,System.Int32@)~System.IntPtr")]

View File

@ -7,10 +7,10 @@ namespace Kyoo.InternalAPI
public interface ITranscoder
{
//Should transcode to a mp4 container (same video/audio format if possible, no subtitles).
string Transmux(WatchItem episode);
Task<string> Transmux(WatchItem episode);
//Should transcode to a mp4 container with a h264 video format and a AAC audio format, no subtitles.
string Transcode(string path);
Task<string> Transcode(WatchItem episode);
//Extract all subtitles of a video and save them in the subtitles sub-folder.
Task<Track[]> ExtractSubtitles(string path);

View File

@ -31,22 +31,29 @@ namespace Kyoo.InternalAPI
});
}
public string Transmux(WatchItem episode)
public async Task<string> Transmux(WatchItem episode)
{
string folder = Path.Combine(transmuxPath, episode.Link);
string manifest = Path.Combine(folder, episode.Link + ".mpd");
float playableDuration = 0;
bool transmuxFailed = false;
Directory.CreateDirectory(folder);
Debug.WriteLine("&Transmuxing " + episode.Link + " at " + episode.Path + ", outputPath: " + folder);
//FFMPEG require us to put DirectorySeparaorChar as '/' for his internal regex.
if (File.Exists(manifest) || TranscoderAPI.transmux(episode.Path, manifest.Replace('\\', '/')) == 0)
if (File.Exists(manifest))
return manifest;
else
return null;
Task.Run(() =>
{
transmuxFailed = TranscoderAPI.transmux(episode.Path, manifest.Replace('\\', '/'), out playableDuration) != 0;
playableDuration = float.MaxValue;
});
while (playableDuration < 20 || (!File.Exists(manifest) && !transmuxFailed))
await Task.Delay(10);
return transmuxFailed ? null : manifest;
}
public string Transcode(string path)
public Task<string> Transcode(WatchItem episode)
{
//NOT IMPLEMENTED YET
return null;

View File

@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Kyoo.Models;
using Kyoo.Models.Watch;
@ -14,7 +15,7 @@ namespace Kyoo.InternalAPI.TranscoderLink
public extern static int Init();
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
public extern static int transmux(string path, string out_path);
public extern static int transmux(string path, string out_path, out float playableDuration);
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
private extern static IntPtr extract_subtitles(string path, string out_path, out int array_length, out int track_count);