mirror of
https://github.com/zoriya/Kyoo.Transcoder.git
synced 2026-08-16 02:44:44 +00:00
Reworking the subtitle extraction
This commit is contained in:
+1
-1
@@ -9,7 +9,7 @@ include_directories(include)
|
||||
add_library(transcoder SHARED
|
||||
src/helper.c
|
||||
src/subtitles.c
|
||||
src/info.c)
|
||||
src/info.c src/path_helper.c)
|
||||
set_property(TARGET transcoder PROPERTY C_STANDARD 11)
|
||||
|
||||
target_link_libraries(transcoder
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
//
|
||||
// Created by anonymus-raccoon on 12/29/19.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
char *path_getfolder(const char *path);
|
||||
|
||||
char *get_extension_from_codec(char *codec);
|
||||
@@ -11,4 +11,6 @@
|
||||
//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.
|
||||
API stream *extract_subtitles(char *path, const char *out_path, unsigned *stream_count, unsigned *subtitle_count);
|
||||
|
||||
API void free_memory(stream *streamsPtr);
|
||||
void destroy_stream(stream *s);
|
||||
|
||||
API void free_streams(stream *streamsPtr, int count);
|
||||
+16
-2
@@ -64,7 +64,21 @@ void process_packet(AVPacket *pkt, AVStream *in_stream, AVStream *out_stream)
|
||||
pkt->pos = -1;
|
||||
}
|
||||
|
||||
void free_memory(stream *stream_ptr)
|
||||
void destroy_stream(stream *s)
|
||||
{
|
||||
free(stream_ptr);
|
||||
if (s->title)
|
||||
free(s->title);
|
||||
if (s->language)
|
||||
free(s->language);
|
||||
if (s->codec)
|
||||
free(s->codec);
|
||||
if (s->path)
|
||||
free(s->path);
|
||||
}
|
||||
|
||||
void free_streams(stream *s, int count)
|
||||
{
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
destroy_stream(s + i);
|
||||
free(s);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// Created by anonymus-raccoon on 12/29/19.
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
char *strrnchr(const char *str, int c, int occ_to_skip)
|
||||
{
|
||||
const char *ptr = str + strlen(str);
|
||||
|
||||
while (ptr != str) {
|
||||
if (*str == c) {
|
||||
occ_to_skip--;
|
||||
if (occ_to_skip == 0)
|
||||
return ((char *)str);
|
||||
}
|
||||
str--;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
char *path_getfolder(const char *path)
|
||||
{
|
||||
char *start;
|
||||
char *end;
|
||||
char *folder;
|
||||
|
||||
start = strrnchr(path, '/', 1);
|
||||
end = strrchr(path, '/');
|
||||
if (!end)
|
||||
return (NULL);
|
||||
folder = strndup(start, end - start);
|
||||
return (folder);
|
||||
}
|
||||
|
||||
char *get_extension_from_codec(char *codec)
|
||||
{
|
||||
if (!codec)
|
||||
return (NULL);
|
||||
if (!strcmp(codec, "subrip"))
|
||||
return(".srt");
|
||||
else if (!strcmp(codec, "ass"))
|
||||
return(".ass");
|
||||
else {
|
||||
printf("Unsupported subtitle codec: %s.\n", codec);
|
||||
free(codec);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
+58
-46
@@ -5,45 +5,44 @@
|
||||
#include "stream.h"
|
||||
#include "helper.h"
|
||||
#include "compatibility.h"
|
||||
#include "path_helper.h"
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <transcoder.h>
|
||||
|
||||
int get_subtitle_data(stream *substream, AVStream *in_stream, const char *folder_name, const char *out_path)
|
||||
{
|
||||
AVDictionaryEntry *languageptr = av_dict_get(in_stream->metadata, "language", NULL, 0);
|
||||
char *extension;
|
||||
char *codec = strdup(avcodec_get_name(in_stream->codecpar->codec_id));
|
||||
char *extension = get_extension_from_codec(codec);
|
||||
char *folder_path;
|
||||
|
||||
if (!codec)
|
||||
return (-1);
|
||||
if (!strcmp(codec, "subrip"))
|
||||
extension = ".srt";
|
||||
else if (!strcmp(codec, "ass"))
|
||||
extension = ".ass";
|
||||
else {
|
||||
printf("Unsupported subtitle codec: %s.\n", codec);
|
||||
free(codec);
|
||||
return (-1);
|
||||
}
|
||||
if (!extension)
|
||||
return (-1);
|
||||
*substream = (stream) {
|
||||
NULL,
|
||||
languageptr ? languageptr->value : NULL,
|
||||
languageptr ? strdup(languageptr->value) : NULL,
|
||||
codec,
|
||||
in_stream->disposition & AV_DISPOSITION_DEFAULT,
|
||||
in_stream->disposition & AV_DISPOSITION_FORCED,
|
||||
NULL
|
||||
};
|
||||
asprintf(&substream->path, "%s/%s", out_path, substream->language);
|
||||
if (!substream->path || kmkdir(substream->path, 0733) < 0)
|
||||
return (-1);
|
||||
asprintf(&folder_path, "%s/%s", out_path, substream->language);
|
||||
if (!folder_path)
|
||||
return (-1);
|
||||
if (kmkdir(folder_path, 0733) < 0) {
|
||||
free(folder_path);
|
||||
return (-1);
|
||||
}
|
||||
asprintf(&substream->path, "%s/%s.%s%s%s%s", substream->path,
|
||||
folder_name,
|
||||
substream->language,
|
||||
substream->is_default ? ".default" : "",
|
||||
substream->is_forced ? ".forced" : "",
|
||||
extension);
|
||||
free(folder_path);
|
||||
if (!substream->path)
|
||||
return (-1);
|
||||
return (0);
|
||||
@@ -110,42 +109,55 @@ void finish_up(AVFormatContext *int_ctx, AVFormatContext **output_list, unsigned
|
||||
free(output_list);
|
||||
}
|
||||
|
||||
int split_inputfile(AVFormatContext *int_ctx, AVFormatContext **output_list, stream *streams, char *path, const char *out_path)
|
||||
{
|
||||
int subcount = 0;
|
||||
char *folder_name = path_getfolder(path);
|
||||
|
||||
if (!folder_name)
|
||||
return (-1);
|
||||
for (unsigned int i = 0; i < int_ctx->nb_streams; i++) {
|
||||
AVStream *in_stream = int_ctx->streams[i];
|
||||
|
||||
if (in_stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
|
||||
if (get_subtitle_data(streams + i, in_stream, folder_name, out_path) == 0 &&
|
||||
copy_subtitle_stream(output_list[i], streams + i, int_ctx, in_stream) == 0) {
|
||||
subcount += 1;
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr,"Couldn't copy the %s subtitle to output\n", streams[i].language);
|
||||
destroy_stream(&streams[i]);
|
||||
}
|
||||
streams[i] = NULLSTREAM;
|
||||
output_list[i] = NULL;
|
||||
}
|
||||
free(folder_name);
|
||||
return (subcount);
|
||||
}
|
||||
|
||||
stream *extract_subtitles(char *path, const char *out_path, unsigned *stream_count, unsigned *subtitle_count)
|
||||
{
|
||||
AVFormatContext *int_ctx = NULL;
|
||||
AVFormatContext **output_list;
|
||||
stream *streams;
|
||||
char *folder_name = strchr(path, '/');
|
||||
char *p;
|
||||
stream *streams;
|
||||
|
||||
if (!folder_name && (folder_name = strdup(folder_name)))
|
||||
return (NULL);
|
||||
p = strchr(folder_name, '.');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
if (open_input_context(&int_ctx, path) != 0)
|
||||
return (NULL);
|
||||
return (NULL);
|
||||
*stream_count = int_ctx->nb_streams;
|
||||
*subtitle_count = 0;
|
||||
streams = malloc(sizeof(stream) * *stream_count);
|
||||
streams = calloc(sizeof(stream), *stream_count);
|
||||
output_list = malloc(sizeof(AVFormatContext *) * *stream_count);
|
||||
if (!streams || !output_list)
|
||||
return (NULL);
|
||||
for (unsigned int i = 0; i < *stream_count; i++) {
|
||||
AVStream *in_stream = int_ctx->streams[i];
|
||||
|
||||
if (in_stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
|
||||
if (get_subtitle_data(streams + i, in_stream, folder_name, out_path) == 0) {
|
||||
if (copy_subtitle_stream(output_list[i], streams + i, int_ctx, in_stream) == 0) {
|
||||
*subtitle_count += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
streams[i] = NULLSTREAM;
|
||||
output_list[i] = NULL;
|
||||
}
|
||||
write_data(int_ctx, output_list, *stream_count);
|
||||
finish_up(int_ctx, output_list, *stream_count);
|
||||
return (streams);
|
||||
if (streams && output_list) {
|
||||
*subtitle_count = split_inputfile(int_ctx, output_list, streams, path, out_path);
|
||||
if (*subtitle_count >= 0) {
|
||||
write_data(int_ctx, output_list, *stream_count);
|
||||
finish_up(int_ctx, output_list, *stream_count);
|
||||
return (streams);
|
||||
}
|
||||
}
|
||||
*subtitle_count = 0;
|
||||
if (streams)
|
||||
free_streams(streams, (int)*stream_count);
|
||||
if (output_list)
|
||||
free(output_list);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
+9
-2
@@ -3,15 +3,22 @@
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "transcoder.h"
|
||||
#include "stream.h"
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
unsigned stream_count = 0;
|
||||
unsigned subtitle_count = 0;
|
||||
stream *streams;
|
||||
|
||||
if (argc == 3 && !strcmp(argv[1], "es"))
|
||||
extract_subtitles(argv[2], "./", &stream_count, &subtitle_count);
|
||||
if (argc == 3 && !strcmp(argv[1], "subextract")) {
|
||||
streams = extract_subtitles(argv[2], ".", &stream_count, &subtitle_count);
|
||||
free_streams(streams, stream_count);
|
||||
} else
|
||||
printf("\nUsage:\n\n\
|
||||
%s subextr video_path - Test subtitle extractions\n", argv[0]);
|
||||
return (0);
|
||||
}
|
||||
Reference in New Issue
Block a user