// Kyoo - A portable and vast media library solution.
// Copyright (c) Kyoo.
//
// See AUTHORS.md and LICENSE file in the project root for full license information.
//
// Kyoo is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// Kyoo is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see .
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Kyoo.Abstractions.Controllers;
using Kyoo.Abstractions.Models;
using Kyoo.Core.Models.Options;
using Kyoo.Core.Models.Watch;
using Kyoo.Utils;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Kyoo.Core.Controllers
{
///
/// The transcoder used by the .
///
public class Transcoder : ITranscoder
{
#pragma warning disable IDE1006
///
/// The class that interact with the transcoder written in C.
///
private static class TranscoderAPI
{
///
/// The name of the library. For windows '.dll' should be appended, on linux or macos it should be prefixed
/// by 'lib' and '.so' or '.dylib' should be appended.
///
private const string TranscoderPath = "transcoder";
///
/// Initialize the C library, setup the logger and return the size of a .
///
/// The size of a
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
private static extern int init();
///
/// Initialize the C library, setup the logger and return the size of a .
///
/// The size of a
public static int Init() => init();
///
/// Transmux the file at the specified path. The path must be a local one with '/' as a separator.
///
/// The path of a local file with '/' as a separators.
/// The path of the hls output file.
///
/// The number of seconds currently playable. This is incremented as the file gets transmuxed.
///
/// 0 on success, non 0 on failure.
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)]
private static extern int transmux(string path, string outPath, out float playableDuration);
///
/// Transmux the file at the specified path. The path must be a local one.
///
/// The path of a local file.
/// The path of the hls output file.
///
/// The number of seconds currently playable. This is incremented as the file gets transmuxed.
///
/// 0 on success, non 0 on failure.
public static int Transmux(string path, string outPath, out float playableDuration)
{
path = path.Replace('\\', '/');
outPath = outPath.Replace('\\', '/');
return transmux(path, outPath, out playableDuration);
}
///
/// Retrieve tracks from a video file and extract subtitles, fonts and chapters to an external file.
///
///
/// The path of the video file to analyse. This must be a local path with '/' as a separator.
///
/// The directory that will be used to store extracted files.
/// The size of the returned array.
/// The number of tracks in the returned array.
/// Should the cache be invalidated and information re-extracted or not?
/// A pointer to an array of
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)]
private static extern IntPtr extract_infos(string path,
string outPath,
out uint length,
out uint trackCount,
bool reExtract);
///
/// An helper method to free an array of .
///
/// A pointer to the first element of the array
/// The number of items in the array.
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
private static extern void free_streams(IntPtr streams, uint count);
///
/// Retrieve tracks from a video file and extract subtitles, fonts and chapters to an external file.
///
/// The path of the video file to analyse. This must be a local path.
/// The directory that will be used to store extracted files.
/// Should the cache be invalidated and information re-extracted or not?
/// An array of .
public static Track[] ExtractInfos(string path, string outPath, bool reExtract)
{
path = path.Replace('\\', '/');
outPath = outPath.Replace('\\', '/');
int size = Marshal.SizeOf();
IntPtr ptr = extract_infos(path, outPath, out uint arrayLength, out uint trackCount, reExtract);
IntPtr streamsPtr = ptr;
Track[] tracks;
if (trackCount > 0 && ptr != IntPtr.Zero)
{
tracks = new Track[trackCount];
int j = 0;
for (int i = 0; i < arrayLength; i++)
{
FTrack stream = Marshal.PtrToStructure(streamsPtr);
if (stream!.Type != FTrackType.Unknown && stream.Type != FTrackType.Attachment)
{
tracks[j] = stream.ToTrack();
j++;
}
streamsPtr += size;
}
}
else
tracks = Array.Empty