mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Creating a Transmux function and cleaning up the Transcoder code.
This commit is contained in:
parent
6534ea2e99
commit
3c47c88767
@ -21,33 +21,178 @@ int Init()
|
||||
return 42;
|
||||
}
|
||||
|
||||
Stream* ExtractSubtitles(const char* path, const char* outPath, int* streamCount)
|
||||
{
|
||||
AVFormatContext* inputContext = NULL;
|
||||
|
||||
if (avformat_open_input(&inputContext, path, NULL, NULL))
|
||||
#pragma region InternalProcess
|
||||
int open_input_context(AVFormatContext **inputContext, const char *path)
|
||||
{
|
||||
if (avformat_open_input(inputContext, path, NULL, NULL))
|
||||
{
|
||||
std::cout << "Error: Can't open the file at " << path << std::endl;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (avformat_find_stream_info(inputContext, NULL) < 0)
|
||||
if (avformat_find_stream_info(*inputContext, NULL) < 0)
|
||||
{
|
||||
std::cout << "Error: Could't find streams informations for the file at " << path << std::endl;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
av_dump_format(inputContext, 0, path, false);
|
||||
av_dump_format(*inputContext, 0, path, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<Stream>* subtitleStreams = new std::vector<Stream>();
|
||||
AVStream* copy_stream_to_output(AVFormatContext *outputContext, AVStream *inputStream)
|
||||
{
|
||||
AVStream *outputStream = avformat_new_stream(outputContext, NULL);
|
||||
if (outputStream == NULL)
|
||||
{
|
||||
std::cout << "Error: Couldn't create stream." << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (avcodec_parameters_copy(outputStream->codecpar, inputStream->codecpar) < 0)
|
||||
{
|
||||
std::cout << "Error: Couldn't copy parameters to the output file." << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
outputStream->codecpar->codec_tag = 0;
|
||||
|
||||
avformat_transfer_internal_stream_timing_info(outputContext->oformat, outputStream, inputStream, AVTimebaseSource::AVFMT_TBCF_AUTO);
|
||||
outputStream->time_base = av_add_q(av_stream_get_codec_timebase(outputStream), AVRational{ 0, 1 });
|
||||
outputStream->duration = av_rescale_q(inputStream->duration, inputStream->time_base, outputStream->time_base);
|
||||
outputStream->disposition = inputStream->disposition;
|
||||
|
||||
av_dict_copy(&outputStream->metadata, inputStream->metadata, NULL);
|
||||
|
||||
//if (inputStream->nb_side_data)
|
||||
//{
|
||||
// for (int i = 0; i < inputStream->nb_side_data; i++)
|
||||
// {
|
||||
// std::cout << "Copying side packet #" << i << std::endl;
|
||||
|
||||
// AVPacketSideData *sidePkt = &inputStream->side_data[i];
|
||||
// uint8_t *newPkt = av_stream_new_side_data(outputStream, sidePkt->type, sidePkt->size);
|
||||
// if (newPkt == NULL)
|
||||
// {
|
||||
// std::cout << "Error copying side package." << std::endl;
|
||||
// //Should handle return here
|
||||
// return;
|
||||
// }
|
||||
// memcpy(newPkt, sidePkt->data, sidePkt->size);
|
||||
// }
|
||||
//}
|
||||
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
int open_output_file_for_write(AVFormatContext *outputContext, const char* outputPath)
|
||||
{
|
||||
if (!(outputContext->flags & AVFMT_NOFILE))
|
||||
{
|
||||
if (avio_open(&outputContext->pb, outputPath, AVIO_FLAG_WRITE) < 0)
|
||||
{
|
||||
std::cout << "Error: Couldn't open file at " << outputPath << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
std::cout << "Output flag set to AVFMT_NOFILE." << std::endl;
|
||||
|
||||
if (avformat_write_header(outputContext, NULL) < 0)
|
||||
{
|
||||
std::cout << "Error: Couldn't write headers to file at " << outputPath << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void process_packet(AVPacket pkt, AVStream* inputStream, AVStream* outputStream)
|
||||
{
|
||||
pkt.pts = av_rescale_q_rnd(pkt.pts, inputStream->time_base, outputStream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
|
||||
pkt.dts = av_rescale_q_rnd(pkt.dts, inputStream->time_base, outputStream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
|
||||
pkt.duration = av_rescale_q(pkt.duration, inputStream->time_base, outputStream->time_base);
|
||||
pkt.pos = -1;
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Should add goto end;
|
||||
int Transmux(const char *path, const char *outPath)
|
||||
{
|
||||
AVFormatContext *inputContext = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (open_input_context(&inputContext, path) != 0)
|
||||
return 1;
|
||||
|
||||
AVFormatContext *outputContext = NULL;
|
||||
if (avformat_alloc_output_context2(&outputContext, NULL, NULL, outPath) < 0)
|
||||
{
|
||||
std::cout << "Error: Couldn't create an output file." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < inputContext->nb_streams; i++)
|
||||
{
|
||||
AVStream *stream = inputContext->streams[i];
|
||||
if(stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) //Should support multi-audio on a good format.
|
||||
if (copy_stream_to_output(outputContext, stream) == NULL)
|
||||
return 1;
|
||||
}
|
||||
|
||||
av_dump_format(outputContext, 0, outPath, true);
|
||||
if (open_output_file_for_write(outputContext, outPath) != 0)
|
||||
return 1;
|
||||
|
||||
AVPacket pkt;
|
||||
while (av_read_frame(inputContext, &pkt) == 0)
|
||||
{
|
||||
if (pkt.stream_index >= outputContext->nb_streams)
|
||||
continue;
|
||||
|
||||
AVStream *inputStream = inputContext->streams[pkt.stream_index];
|
||||
AVStream *outputStream = outputContext->streams[pkt.stream_index];
|
||||
|
||||
process_packet(pkt, inputStream, outputStream);
|
||||
if (av_interleaved_write_frame(outputContext, &pkt) < 0)
|
||||
std::cout << "Error while writing a packet to the output file." << std::endl;
|
||||
|
||||
av_packet_unref(&pkt);
|
||||
}
|
||||
|
||||
|
||||
avformat_close_input(&inputContext);
|
||||
av_write_trailer(outputContext);
|
||||
|
||||
if (outputContext && !(outputContext->flags & AVFMT_NOFILE))
|
||||
avio_closep(&outputContext->pb);
|
||||
avformat_free_context(outputContext);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Stream *ExtractSubtitles(const char *path, const char *outPath, int *streamCount)
|
||||
{
|
||||
AVFormatContext *inputContext = NULL;
|
||||
|
||||
if (open_input_context(&inputContext, path) != 0)
|
||||
return 0;
|
||||
|
||||
std::vector<Stream> *subtitleStreams = new std::vector<Stream>();
|
||||
const unsigned int outputCount = inputContext->nb_streams;
|
||||
AVFormatContext** outputList = new AVFormatContext*[outputCount];
|
||||
AVFormatContext **outputList = new AVFormatContext*[outputCount];
|
||||
|
||||
//Initialize output and set headers.
|
||||
for (unsigned int i = 0; i < inputContext->nb_streams; i++)
|
||||
{
|
||||
AVStream* inputStream = inputContext->streams[i];
|
||||
const AVCodecParameters* inputCodecpar = inputStream->codecpar;
|
||||
AVStream *inputStream = inputContext->streams[i];
|
||||
const AVCodecParameters *inputCodecpar = inputStream->codecpar;
|
||||
|
||||
if (inputCodecpar->codec_type != AVMEDIA_TYPE_SUBTITLE)
|
||||
outputList[i] = NULL;
|
||||
@ -62,7 +207,7 @@ Stream* ExtractSubtitles(const char* path, const char* outPath, int* streamCount
|
||||
NULL); //Path builder references
|
||||
|
||||
//Create the language subfolder
|
||||
std::stringstream outStream /*= new std::stringstream()*/;
|
||||
std::stringstream outStream;
|
||||
outStream << outPath << (char)std::filesystem::path::preferred_separator << stream.language;
|
||||
std::filesystem::create_directory(outStream.str());
|
||||
|
||||
@ -90,7 +235,7 @@ Stream* ExtractSubtitles(const char* path, const char* outPath, int* streamCount
|
||||
subtitleStreams->push_back(stream);
|
||||
std::cout << "Stream #" << i << "(" << stream.language << "), stream type: " << inputCodecpar->codec_type << " codec: " << stream.codec << std::endl;
|
||||
|
||||
AVFormatContext* outputContext = NULL;
|
||||
AVFormatContext *outputContext = NULL;
|
||||
if (avformat_alloc_output_context2(&outputContext, NULL, NULL, stream.path) < 0)
|
||||
{
|
||||
std::cout << "Error: Couldn't create an output file." << std::endl;
|
||||
@ -99,63 +244,14 @@ Stream* ExtractSubtitles(const char* path, const char* outPath, int* streamCount
|
||||
|
||||
av_dict_copy(&outputContext->metadata, inputContext->metadata, NULL);
|
||||
|
||||
AVStream* outputStream = avformat_new_stream(outputContext, NULL);
|
||||
AVStream* outputStream = copy_stream_to_output(outputContext, inputStream);
|
||||
if (outputStream == NULL)
|
||||
{
|
||||
std::cout << "Error: Couldn't create stream." << std::endl;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (avcodec_parameters_copy(outputStream->codecpar, inputCodecpar) < 0)
|
||||
{
|
||||
std::cout << "Error: Couldn't copy parameters to the output file." << std::endl;
|
||||
goto end;
|
||||
}
|
||||
outputStream->codecpar->codec_tag = 0;
|
||||
|
||||
avformat_transfer_internal_stream_timing_info(outputContext->oformat, outputStream, inputStream, AVTimebaseSource::AVFMT_TBCF_AUTO);
|
||||
outputStream->time_base = av_add_q(av_stream_get_codec_timebase(outputStream), AVRational { 0, 1 });
|
||||
outputStream->duration = av_rescale_q(inputStream->duration, inputStream->time_base, outputStream->time_base);
|
||||
outputStream->disposition = inputStream->disposition;
|
||||
|
||||
av_dict_copy(&outputStream->metadata, inputStream->metadata, NULL);
|
||||
|
||||
//if (inputStream->nb_side_data)
|
||||
//{
|
||||
// for (int i = 0; i < inputStream->nb_side_data; i++)
|
||||
// {
|
||||
// std::cout << "Copying side packet #" << i << std::endl;
|
||||
|
||||
// AVPacketSideData* sidePkt = &inputStream->side_data[i];
|
||||
// uint8_t* newPkt = av_stream_new_side_data(outputStream, sidePkt->type, sidePkt->size);
|
||||
// if (newPkt == NULL)
|
||||
// {
|
||||
// std::cout << "Error copying side package." << std::endl;
|
||||
// //Should handle return here
|
||||
// return;
|
||||
// }
|
||||
// memcpy(newPkt, sidePkt->data, sidePkt->size);
|
||||
// }
|
||||
//}
|
||||
|
||||
av_dump_format(outputContext, 0, stream.path, true);
|
||||
|
||||
if (!(outputContext->flags & AVFMT_NOFILE))
|
||||
{
|
||||
if (avio_open(&outputContext->pb, stream.path, AVIO_FLAG_WRITE) < 0)
|
||||
{
|
||||
std::cout << "Error: Couldn't open file at " << stream.path << std::endl;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
std::cout << "Output flag set to AVFMT_NOFILE." << std::endl;
|
||||
|
||||
if (avformat_write_header(outputContext, NULL) < 0)
|
||||
{
|
||||
std::cout << "Error: Couldn't write headers to file at " << stream.path << std::endl;
|
||||
if (open_output_file_for_write(outputContext, stream.path) != 0)
|
||||
goto end;
|
||||
}
|
||||
|
||||
outputList[i] = outputContext;
|
||||
|
||||
@ -179,22 +275,18 @@ Stream* ExtractSubtitles(const char* path, const char* outPath, int* streamCount
|
||||
if (pkt.stream_index >= outputCount)
|
||||
continue;
|
||||
|
||||
AVFormatContext* outputContext = outputList[pkt.stream_index];
|
||||
AVFormatContext *outputContext = outputList[pkt.stream_index];
|
||||
if(outputContext == nullptr)
|
||||
{
|
||||
av_packet_unref(&pkt);
|
||||
continue;
|
||||
}
|
||||
|
||||
AVStream* inputStream = inputContext->streams[pkt.stream_index];
|
||||
AVStream* outputStream = outputContext->streams[0];
|
||||
AVStream *inputStream = inputContext->streams[pkt.stream_index];
|
||||
AVStream *outputStream = outputContext->streams[0];
|
||||
|
||||
pkt.stream_index = 0;
|
||||
|
||||
pkt.pts = av_rescale_q_rnd(pkt.pts, inputStream->time_base, outputStream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
|
||||
pkt.dts = av_rescale_q_rnd(pkt.dts, inputStream->time_base, outputStream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
|
||||
pkt.duration = av_rescale_q(pkt.duration, inputStream->time_base, outputStream->time_base);
|
||||
pkt.pos = -1;
|
||||
process_packet(pkt, inputStream, outputStream);
|
||||
|
||||
if (av_interleaved_write_frame(outputContext, &pkt) < 0)
|
||||
{
|
||||
@ -208,7 +300,7 @@ Stream* ExtractSubtitles(const char* path, const char* outPath, int* streamCount
|
||||
|
||||
for (unsigned int i = 0; i < outputCount; i++)
|
||||
{
|
||||
AVFormatContext* outputContext = outputList[i];
|
||||
AVFormatContext *outputContext = outputList[i];
|
||||
|
||||
if (outputContext == NULL)
|
||||
continue;
|
||||
|
@ -13,3 +13,5 @@ extern "C" API int Init();
|
||||
|
||||
//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* ExtractSubtitles(const char* path, const char* outPath, int* streamsCount);
|
||||
|
||||
extern "C" API int Transmux(const char* path, const char* outPath);
|
||||
|
@ -32,7 +32,8 @@
|
||||
"scripts": [
|
||||
"./node_modules/jquery/dist/jquery.min.js",
|
||||
"./node_modules/bootstrap/dist/js/bootstrap.bundle.min.js",
|
||||
"./src/libraries/subtitles.js"
|
||||
"./src/libraries/subtitles.js",
|
||||
"./node_modules/video.js/dist/video.min.js"
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
|
224
Kyoo/ClientApp/package-lock.json
generated
224
Kyoo/ClientApp/package-lock.json
generated
@ -1134,6 +1134,21 @@
|
||||
"integrity": "sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/runtime": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.2.tgz",
|
||||
"integrity": "sha512-EXxN64agfUqqIGeEjI5dL5z0Sw0ZwWo1mLTi4mQowCZ42O59b7DRpZAnTC6OqdF28wMBMFKNb/4uFGrVaigSpg==",
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.13.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"regenerator-runtime": {
|
||||
"version": "0.13.3",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz",
|
||||
"integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@babel/template": {
|
||||
"version": "7.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz",
|
||||
@ -1349,6 +1364,20 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@videojs/http-streaming": {
|
||||
"version": "1.10.6",
|
||||
"resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-1.10.6.tgz",
|
||||
"integrity": "sha512-uPBuunHnxWeFRYxRX0j6h1IIWv3+QKvSkZGmW9TvqxWBqeNGSrQymR6tm1nVjQ2HhMVxVphQTUhUTTPDVWqmQg==",
|
||||
"requires": {
|
||||
"aes-decrypter": "3.0.0",
|
||||
"global": "^4.3.0",
|
||||
"m3u8-parser": "4.4.0",
|
||||
"mpd-parser": "0.8.1",
|
||||
"mux.js": "5.2.1",
|
||||
"url-toolkit": "^2.1.3",
|
||||
"video.js": "^6.8.0 || ^7.0.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/ast": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
|
||||
@ -1575,6 +1604,16 @@
|
||||
"integrity": "sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw==",
|
||||
"dev": true
|
||||
},
|
||||
"aes-decrypter": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/aes-decrypter/-/aes-decrypter-3.0.0.tgz",
|
||||
"integrity": "sha1-eEihwUW5/b9Xrj4rWxvHzwZEqPs=",
|
||||
"requires": {
|
||||
"commander": "^2.9.0",
|
||||
"global": "^4.3.2",
|
||||
"pkcs7": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"after": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
|
||||
@ -2791,8 +2830,7 @@
|
||||
"commander": {
|
||||
"version": "2.20.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
|
||||
"integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ=="
|
||||
},
|
||||
"commondir": {
|
||||
"version": "1.0.1",
|
||||
@ -3203,7 +3241,6 @@
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
|
||||
"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"object-keys": "^1.0.12"
|
||||
}
|
||||
@ -3415,6 +3452,11 @@
|
||||
"void-elements": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"dom-walk": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz",
|
||||
"integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg="
|
||||
},
|
||||
"domain-browser": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
|
||||
@ -3631,7 +3673,6 @@
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
|
||||
"integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es-to-primitive": "^1.2.0",
|
||||
"function-bind": "^1.1.1",
|
||||
@ -3645,7 +3686,6 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
|
||||
"integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-callable": "^1.1.4",
|
||||
"is-date-object": "^1.0.1",
|
||||
@ -4130,6 +4170,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"for-each": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
|
||||
"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
|
||||
"requires": {
|
||||
"is-callable": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"for-in": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
|
||||
@ -4250,8 +4298,7 @@
|
||||
"function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
|
||||
"dev": true
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
||||
},
|
||||
"genfun": {
|
||||
"version": "5.0.0",
|
||||
@ -4324,6 +4371,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"global": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
|
||||
"integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=",
|
||||
"requires": {
|
||||
"min-document": "^2.19.0",
|
||||
"process": "~0.5.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"process": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
|
||||
"integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8="
|
||||
}
|
||||
}
|
||||
},
|
||||
"globals": {
|
||||
"version": "9.18.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
|
||||
@ -4409,7 +4472,6 @@
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
@ -4455,8 +4517,7 @@
|
||||
"has-symbols": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
|
||||
"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
|
||||
"dev": true
|
||||
"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q="
|
||||
},
|
||||
"has-value": {
|
||||
"version": "1.0.0",
|
||||
@ -4803,6 +4864,11 @@
|
||||
"integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=",
|
||||
"dev": true
|
||||
},
|
||||
"individual": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/individual/-/individual-2.0.0.tgz",
|
||||
"integrity": "sha1-gzsJfa0jKU52EXqY+zjg2a1hu5c="
|
||||
},
|
||||
"infer-owner": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
|
||||
@ -4956,8 +5022,7 @@
|
||||
"is-callable": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
|
||||
"integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA=="
|
||||
},
|
||||
"is-data-descriptor": {
|
||||
"version": "0.1.4",
|
||||
@ -4982,8 +5047,7 @@
|
||||
"is-date-object": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
|
||||
"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
|
||||
"dev": true
|
||||
"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY="
|
||||
},
|
||||
"is-descriptor": {
|
||||
"version": "0.1.6",
|
||||
@ -5037,6 +5101,11 @@
|
||||
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
|
||||
"dev": true
|
||||
},
|
||||
"is-function": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz",
|
||||
"integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU="
|
||||
},
|
||||
"is-glob": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
|
||||
@ -5101,7 +5170,6 @@
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
|
||||
"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has": "^1.0.1"
|
||||
}
|
||||
@ -5116,7 +5184,6 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
|
||||
"integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-symbols": "^1.0.0"
|
||||
}
|
||||
@ -6312,6 +6379,11 @@
|
||||
"source-map-support": "^0.5.5"
|
||||
}
|
||||
},
|
||||
"keycode": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz",
|
||||
"integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ="
|
||||
},
|
||||
"killable": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
|
||||
@ -6488,6 +6560,14 @@
|
||||
"yallist": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"m3u8-parser": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-4.4.0.tgz",
|
||||
"integrity": "sha512-iH2AygTFILtato+XAgnoPYzLHM4R3DjATj7Ozbk7EHdB2XoLF2oyOUguM7Kc4UVHbQHHL/QPaw98r7PbWzG0gg==",
|
||||
"requires": {
|
||||
"global": "^4.3.2"
|
||||
}
|
||||
},
|
||||
"magic-string": {
|
||||
"version": "0.25.3",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.3.tgz",
|
||||
@ -6787,6 +6867,14 @@
|
||||
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||
"dev": true
|
||||
},
|
||||
"min-document": {
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
|
||||
"integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
|
||||
"requires": {
|
||||
"dom-walk": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"mini-css-extract-plugin": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.0.tgz",
|
||||
@ -6933,6 +7021,15 @@
|
||||
"run-queue": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"mpd-parser": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.8.1.tgz",
|
||||
"integrity": "sha512-WBTJ1bKk8OLUIxBh6s1ju1e2yz/5CzhPbgi6P3F3kJHKhGy1Z+ElvEnuzEbtC/dnbRcJtMXazE3f93N5LLdp9Q==",
|
||||
"requires": {
|
||||
"global": "^4.3.2",
|
||||
"url-toolkit": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
@ -6961,6 +7058,11 @@
|
||||
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
|
||||
"dev": true
|
||||
},
|
||||
"mux.js": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/mux.js/-/mux.js-5.2.1.tgz",
|
||||
"integrity": "sha512-1t2payD3Y8izfZRq7tfUQlhL2fKzjeLr9v1/2qNCTkEQnd9Abtn1JgzsBgGZubEXh6lM5L8B0iLGoWQiukjtbQ=="
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.14.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
|
||||
@ -7270,8 +7372,7 @@
|
||||
"object-keys": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
||||
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
|
||||
},
|
||||
"object-visit": {
|
||||
"version": "1.0.1",
|
||||
@ -7586,6 +7687,15 @@
|
||||
"safe-buffer": "^5.1.1"
|
||||
}
|
||||
},
|
||||
"parse-headers": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.2.tgz",
|
||||
"integrity": "sha512-/LypJhzFmyBIDYP9aDVgeyEb5sQfbfY5mnDq4hVhlQ69js87wXfmEI5V3xI6vvXasqebp0oCytYFLxsBVfCzSg==",
|
||||
"requires": {
|
||||
"for-each": "^0.3.3",
|
||||
"string.prototype.trim": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"parse-json": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
|
||||
@ -7743,6 +7853,11 @@
|
||||
"pinkie": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"pkcs7": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pkcs7/-/pkcs7-1.0.2.tgz",
|
||||
"integrity": "sha1-ttulJ1KMKUK/wSLOLa/NteWQdOc="
|
||||
},
|
||||
"pkg-dir": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
|
||||
@ -8557,6 +8672,14 @@
|
||||
"aproba": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"rust-result": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/rust-result/-/rust-result-1.0.0.tgz",
|
||||
"integrity": "sha1-NMdbLm3Dn+WHXlveyFteD5FTb3I=",
|
||||
"requires": {
|
||||
"individual": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"rxjs": {
|
||||
"version": "6.4.0",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz",
|
||||
@ -8571,6 +8694,14 @@
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"dev": true
|
||||
},
|
||||
"safe-json-parse": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-4.0.0.tgz",
|
||||
"integrity": "sha1-fA9XjPzNEtM6ccDgVBPi7KFx6qw=",
|
||||
"requires": {
|
||||
"rust-result": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"safe-regex": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
|
||||
@ -9579,6 +9710,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"string.prototype.trim": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.0.tgz",
|
||||
"integrity": "sha512-9EIjYD/WdlvLpn987+ctkLf0FfvBefOCuiEr2henD8X+7jfwPnyvTdmW8OJhj5p+M0/96mBdynLWkxUr+rHlpg==",
|
||||
"requires": {
|
||||
"define-properties": "^1.1.3",
|
||||
"es-abstract": "^1.13.0",
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
@ -10172,6 +10313,11 @@
|
||||
"requires-port": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"url-toolkit": {
|
||||
"version": "2.1.6",
|
||||
"resolved": "https://registry.npmjs.org/url-toolkit/-/url-toolkit-2.1.6.tgz",
|
||||
"integrity": "sha512-UaZ2+50am4HwrV2crR/JAf63Q4VvPYphe63WGeoJxeu8gmOm0qxPt+KsukfakPNrX9aymGNEkkaoICwn+OuvBw=="
|
||||
},
|
||||
"use": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
|
||||
@ -10286,6 +10432,34 @@
|
||||
"extsprintf": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"video.js": {
|
||||
"version": "7.6.5",
|
||||
"resolved": "https://registry.npmjs.org/video.js/-/video.js-7.6.5.tgz",
|
||||
"integrity": "sha512-r0kC9SNJhXz9th/wwbRaLVOIZTvXkF+rhFq9/FWU+e+EJClwClRCgP8STGmfrPHDXrfWiJwH9YY21JZK61vGGQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.4.5",
|
||||
"@videojs/http-streaming": "1.10.6",
|
||||
"global": "4.3.2",
|
||||
"keycode": "^2.2.0",
|
||||
"safe-json-parse": "4.0.0",
|
||||
"videojs-font": "3.2.0",
|
||||
"videojs-vtt.js": "^0.14.1",
|
||||
"xhr": "2.4.0"
|
||||
}
|
||||
},
|
||||
"videojs-font": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-3.2.0.tgz",
|
||||
"integrity": "sha512-g8vHMKK2/JGorSfqAZQUmYYNnXmfec4MLhwtEFS+mMs2IDY398GLysy6BH6K+aS1KMNu/xWZ8Sue/X/mdQPliA=="
|
||||
},
|
||||
"videojs-vtt.js": {
|
||||
"version": "0.14.1",
|
||||
"resolved": "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.14.1.tgz",
|
||||
"integrity": "sha512-YxOiywx6N9t3J5nqsE5WN2Sw4CSqVe3zV+AZm2T4syOc2buNJaD6ZoexSdeszx2sHLU/RRo2r4BJAXFDQ7Qo2Q==",
|
||||
"requires": {
|
||||
"global": "^4.3.1"
|
||||
}
|
||||
},
|
||||
"vm-browserify": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz",
|
||||
@ -11994,6 +12168,17 @@
|
||||
"ultron": "~1.1.0"
|
||||
}
|
||||
},
|
||||
"xhr": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/xhr/-/xhr-2.4.0.tgz",
|
||||
"integrity": "sha1-4W5mpF+GmGHu76tBbV7/ci3ECZM=",
|
||||
"requires": {
|
||||
"global": "~4.3.0",
|
||||
"is-function": "^1.0.1",
|
||||
"parse-headers": "^2.0.0",
|
||||
"xtend": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"xml2js": {
|
||||
"version": "0.4.19",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
|
||||
@ -12027,8 +12212,7 @@
|
||||
"xtend": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.0",
|
||||
|
@ -27,6 +27,7 @@
|
||||
"popper.js": "^1.15.0",
|
||||
"rxjs": "~6.4.0",
|
||||
"tslib": "^1.10.0",
|
||||
"video.js": "^7.6.5",
|
||||
"zone.js": "~0.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -1,10 +1,8 @@
|
||||
<div id="root">
|
||||
<div class="player">
|
||||
<video id="player" poster="backdrop/{{this.item.showSlug}}" autoplay muted (click)="tooglePlayback()">
|
||||
<video id="player" poster="backdrop/{{this.item.showSlug}}" autoplay muted (click)="tooglePlayback()" class="video-js">
|
||||
<source src="/api/video/{{this.item.link}}" />
|
||||
<source src="/api/video/{{this.item.link}}/stream" type="video/mp4" />
|
||||
|
||||
<!--<track src="/api/subtitle/clannad-s1e1.eng.vtt" lang="English" srclang="en" default/>-->
|
||||
<source src="/api/video/transmux/{{this.item.link}}" type="video/mp4" />
|
||||
</video>
|
||||
</div>
|
||||
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { WatchItem, Track } from "../../models/watch-item";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { DomSanitizer, Title } from "@angular/platform-browser";
|
||||
import { Location } from "@angular/common";
|
||||
import { MatSliderChange } from "@angular/material/slider";
|
||||
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { MatSnackBar } from "@angular/material/snack-bar";
|
||||
import { DomSanitizer, Title } from "@angular/platform-browser";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { Track, WatchItem } from "../../models/watch-item";
|
||||
|
||||
declare var SubtitleManager: any;
|
||||
|
||||
|
@ -22,35 +22,38 @@ namespace Kyoo.Controllers
|
||||
{
|
||||
WatchItem episode = libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber);
|
||||
|
||||
if (System.IO.File.Exists(episode.Path))
|
||||
if (episode != null && System.IO.File.Exists(episode.Path))
|
||||
return PhysicalFile(episode.Path, "video/x-matroska", true);
|
||||
else
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
[HttpGet("{showSlug}-s{seasonNumber}e{episodeNumber}/stream")]
|
||||
public IActionResult Stream(string showSlug, long seasonNumber, long episodeNumber)
|
||||
[HttpGet("transmux/{showSlug}-s{seasonNumber}e{episodeNumber}")]
|
||||
public IActionResult Transmux(string showSlug, long seasonNumber, long episodeNumber)
|
||||
{
|
||||
WatchItem episode = libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber);
|
||||
|
||||
if (System.IO.File.Exists(episode.Path))
|
||||
if (episode != null && System.IO.File.Exists(episode.Path))
|
||||
{
|
||||
string path = transcoder.Stream(episode.Path);
|
||||
return PhysicalFile(path, "video/mp4", true);
|
||||
string path = transcoder.Transmux(episode);
|
||||
if (path != null)
|
||||
return PhysicalFile(path, "video/mp4", true);
|
||||
else
|
||||
return StatusCode(500);
|
||||
}
|
||||
else
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
[HttpGet("{showSlug}-s{seasonNumber}e{episodeNumber}/transcode")]
|
||||
[HttpGet("transcode/{showSlug}-s{seasonNumber}e{episodeNumber}")]
|
||||
public IActionResult Transcode(string showSlug, long seasonNumber, long episodeNumber)
|
||||
{
|
||||
WatchItem episode = libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber);
|
||||
|
||||
if (System.IO.File.Exists(episode.Path))
|
||||
if (episode != null && System.IO.File.Exists(episode.Path))
|
||||
{
|
||||
string path = transcoder.Transcode(episode.Path);
|
||||
return PhysicalFile(path, "video/mp4", true);
|
||||
return PhysicalFile(path, "video/mp4", true); //Should use mpeg dash
|
||||
}
|
||||
else
|
||||
return NotFound();
|
||||
|
@ -6,7 +6,7 @@ namespace Kyoo.InternalAPI
|
||||
public interface ITranscoder
|
||||
{
|
||||
//Should transcode to a mp4 container (same video/audio format if possible, no subtitles).
|
||||
string Stream(string path);
|
||||
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);
|
||||
|
@ -10,8 +10,12 @@ namespace Kyoo.InternalAPI
|
||||
{
|
||||
public class Transcoder : ITranscoder
|
||||
{
|
||||
private readonly string tempPath;
|
||||
|
||||
public Transcoder(IConfiguration config)
|
||||
{
|
||||
tempPath = config.GetValue<string>("tempPath");
|
||||
|
||||
Debug.WriteLine("&Api INIT: " + TranscoderAPI.Init());
|
||||
}
|
||||
|
||||
@ -29,9 +33,14 @@ namespace Kyoo.InternalAPI
|
||||
Debug.WriteLine("&Getting video...");
|
||||
}
|
||||
|
||||
public string Stream(string path)
|
||||
public string Transmux(WatchItem episode)
|
||||
{
|
||||
return @"D:\Videos\Anohana\AnoHana S01E01.mp4";
|
||||
string temp = Path.Combine(tempPath, episode.Link + ".mp4");
|
||||
Debug.WriteLine("&Transmuxing " + episode.Link + " at " + episode.Path + ", outputPath: " + temp);
|
||||
if (File.Exists(temp) || TranscoderAPI.Transmux(episode.Path, temp) == 0)
|
||||
return temp;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public string Transcode(string path)
|
||||
|
@ -12,6 +12,9 @@ namespace Kyoo.InternalAPI.TranscoderLink
|
||||
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static int Init();
|
||||
|
||||
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static int Transmux(string path, string outPath);
|
||||
|
||||
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
|
||||
private extern static IntPtr ExtractSubtitles(string path, string outPath, out int streams);
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"databasePath": "C://Projects/database.db",
|
||||
"tempPath": "C:\\Projects",
|
||||
"peoplePath": "D://Videos/People",
|
||||
"plugins": "C:\\Projects\\Kyoo\\Debug",
|
||||
"providerPlugins": "C://Projects/Plugins/Providers",
|
||||
|
Loading…
x
Reference in New Issue
Block a user