mirror of
https://github.com/zoriya/Kyoo.Transcoder.git
synced 2025-12-06 06:26:11 +00:00
Cleaning up attachment management
This commit is contained in:
@@ -10,4 +10,6 @@ char *path_getfilename(const char *path);
|
||||
|
||||
char *get_extension_from_codec(char *codec);
|
||||
|
||||
int path_mkdir(const char *path, int mode);
|
||||
int path_mkdir(const char *path, int mode);
|
||||
|
||||
int path_mkdir_p(const char *path, int mode);
|
||||
@@ -16,7 +16,7 @@ typedef enum
|
||||
video = 1,
|
||||
audio = 2,
|
||||
subtitle = 3,
|
||||
font = 4
|
||||
attachment = 4
|
||||
} type;
|
||||
|
||||
typedef struct stream
|
||||
@@ -34,6 +34,7 @@ void extract_track(stream *track,
|
||||
const char *out_path,
|
||||
AVStream *stream,
|
||||
AVFormatContext *in_ctx,
|
||||
AVFormatContext **out_ctx);
|
||||
void extract_font(stream *font, const char *out_path, AVStream *stream);
|
||||
AVFormatContext **out_ctx,
|
||||
bool reextract);
|
||||
void extract_attachment(stream *font, const char *out_path, AVStream *stream);
|
||||
void extract_chapters(AVFormatContext *ctx, const char *out_path);
|
||||
@@ -1,3 +1,8 @@
|
||||
//
|
||||
// Created by Anonymus Raccoon on 15/12/2019.
|
||||
//
|
||||
|
||||
|
||||
#pragma once
|
||||
#include "export.h"
|
||||
#include "stream.h"
|
||||
@@ -6,7 +11,11 @@ API int transmux(const char *path, const char *out_path, float *playable_duratio
|
||||
|
||||
//API int transcode(const char *path, const char *out_path, float *playable_duration);
|
||||
|
||||
API stream *extract_infos(const char *path, const char *out_path, unsigned *stream_count, unsigned *track_count);
|
||||
API stream *extract_infos(const char *path,
|
||||
const char *out_path,
|
||||
unsigned *stream_count,
|
||||
unsigned *track_count,
|
||||
bool reextract);
|
||||
|
||||
void destroy_stream(stream *s);
|
||||
|
||||
|
||||
@@ -11,23 +11,14 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
// @return -2 on error, -1 if track has alreaady been extracted, 0 on success.
|
||||
// @return -2 on error, -1 if track has already been extracted, 0 on success.
|
||||
int create_out_path(stream *track, const char *out_path, int track_id)
|
||||
{
|
||||
char *folder_path;
|
||||
char *tmp;
|
||||
|
||||
asprintf(&folder_path, "%s/Subtitles/%s", out_path, track->language ? track->language : "und");
|
||||
if (!folder_path)
|
||||
asprintf(&folder_path, "%s/Extra/Subtitles/%s", out_path, track->language ? track->language : "und");
|
||||
if (path_mkdir_p(folder_path, 0775))
|
||||
return -2;
|
||||
tmp = strrchr(folder_path, '/');
|
||||
*tmp = '\0';
|
||||
if (path_mkdir(folder_path, 0733) < 0)
|
||||
return free(folder_path), -2;
|
||||
*tmp = '/';
|
||||
if (path_mkdir(folder_path, 0733) < 0)
|
||||
return free(folder_path), -2;
|
||||
|
||||
char *extension = get_extension_from_codec(track->codec);
|
||||
char *file_name = path_getfilename(track->path);
|
||||
|
||||
@@ -52,6 +43,7 @@ int create_out_path(stream *track, const char *out_path, int track_id)
|
||||
free(file_name);
|
||||
if (!track->path)
|
||||
return -2;
|
||||
// TODO return 0 if the file has a size of 0.
|
||||
return access(track->path, F_OK) == 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
@@ -72,7 +64,7 @@ int extract_stream(AVFormatContext **out_ctx, stream *s, AVFormatContext *int_ct
|
||||
if (*out_ctx && !((*out_ctx)->flags & AVFMT_NOFILE))
|
||||
avio_closep(&(*out_ctx)->pb);
|
||||
avformat_free_context(*out_ctx);
|
||||
fprintf(stderr, "An error occured, cleaning up th output context for the %s stream.\n", s->language);
|
||||
fprintf(stderr, "An error occurred, cleaning up th output context for the %s stream.\n", s->language);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -80,14 +72,15 @@ void extract_track(stream *track,
|
||||
const char *out_path,
|
||||
AVStream *stream,
|
||||
AVFormatContext *in_ctx,
|
||||
AVFormatContext **out_ctx)
|
||||
AVFormatContext **out_ctx,
|
||||
bool reextract)
|
||||
{
|
||||
if (create_out_path(track, out_path, stream->id) != 0)
|
||||
return;
|
||||
extract_stream(out_ctx, track, in_ctx, stream);
|
||||
int ret = create_out_path(track, out_path, stream->id);
|
||||
if (ret == 0 || (reextract && ret == -1))
|
||||
extract_stream(out_ctx, track, in_ctx, stream);
|
||||
}
|
||||
|
||||
void extract_font(stream *font, const char *out_path, AVStream *stream)
|
||||
void extract_attachment(stream *font, const char *out_path, AVStream *stream)
|
||||
{
|
||||
AVDictionaryEntry *filename = av_dict_get(stream->metadata, "filename", NULL, 0);
|
||||
|
||||
@@ -98,17 +91,17 @@ void extract_font(stream *font, const char *out_path, AVStream *stream)
|
||||
if (!font->path)
|
||||
return;
|
||||
strcpy(font->path, out_path);
|
||||
strcat(font->path, "/Subtitles/fonts/");
|
||||
strcat(font->path, "/Extra/Attachments/");
|
||||
if (path_mkdir(font->path, 0733) < 0)
|
||||
return free(font->path);
|
||||
strcat(font->path, filename->value);
|
||||
int count = strchr(filename->value, '.') - filename->value;
|
||||
long count = strchr(filename->value, '.') - filename->value;
|
||||
if (count > 0)
|
||||
font->title = strndup(filename->value, count);
|
||||
|
||||
int fd = open(font->path, O_WRONLY | O_CREAT, 0644);
|
||||
if (fd == -1)
|
||||
return perror("Kyoo couldn't extract a subtitle's font");
|
||||
return perror("Kyoo couldn't extract an attachment.");
|
||||
write(fd, stream->codecpar->extradata, stream->codecpar->extradata_size);
|
||||
close(fd);
|
||||
}
|
||||
@@ -125,7 +118,7 @@ void extract_chapters(AVFormatContext *ctx, const char *out_path)
|
||||
if (!path)
|
||||
return;
|
||||
strcpy(path, out_path);
|
||||
strcat(path, "/Chapters/");
|
||||
strcat(path, "/Extra/Chapters/");
|
||||
if (path_mkdir(path, 0733) < 0)
|
||||
return;
|
||||
strcat(path, filename);
|
||||
|
||||
@@ -67,9 +67,7 @@ type type_fromffmpeg(AVStream *stream)
|
||||
case AVMEDIA_TYPE_SUBTITLE:
|
||||
return subtitle;
|
||||
case AVMEDIA_TYPE_ATTACHMENT:
|
||||
if (!strcasecmp(avcodec_get_name(stream->codecpar->codec_id), "ttf"))
|
||||
return font;
|
||||
return none;
|
||||
return attachment;
|
||||
default:
|
||||
return none;
|
||||
}
|
||||
|
||||
14
src/info.c
14
src/info.c
@@ -45,7 +45,7 @@ void write_to_outputs(AVFormatContext **output_list, AVFormatContext *in_ctx)
|
||||
}
|
||||
}
|
||||
|
||||
bool list_empty(void **list, int count)
|
||||
bool list_empty(void **list, unsigned count)
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
if (list[i])
|
||||
@@ -69,7 +69,11 @@ stream parse_stream(AVStream *stream, type stream_type, const char *path)
|
||||
};
|
||||
}
|
||||
|
||||
stream *extract_infos(const char *path, const char *out_path, unsigned *stream_count, unsigned *track_count)
|
||||
stream *extract_infos(const char *path,
|
||||
const char *out_path,
|
||||
unsigned *stream_count,
|
||||
unsigned *track_count,
|
||||
bool reextract)
|
||||
{
|
||||
AVFormatContext *ctx = NULL;
|
||||
AVFormatContext **output_list;
|
||||
@@ -92,9 +96,9 @@ stream *extract_infos(const char *path, const char *out_path, unsigned *stream_c
|
||||
*track_count += 1;
|
||||
streams[i] = parse_stream(stream, stream_type, path);
|
||||
if (stream_type == subtitle)
|
||||
extract_track(&streams[i], out_path, stream, ctx, &output_list[i]);
|
||||
if (stream_type == font)
|
||||
extract_font(&streams[i], out_path, stream);
|
||||
extract_track(&streams[i], out_path, stream, ctx, &output_list[i], reextract);
|
||||
if (stream_type == attachment)
|
||||
extract_attachment(&streams[i], out_path, stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ char *path_getfolder(const char *path)
|
||||
char *path_getfilename(const char *path)
|
||||
{
|
||||
const char *name = strrchr(path, '/') ? strrchr(path, '/') + 1 : path;
|
||||
int len = strrchr(path, '.') ? strrchr(path, '.') - name : 1024;
|
||||
long len = strrchr(path, '.') ? strrchr(path, '.') - name : 1024;
|
||||
|
||||
return strndup(name, len);
|
||||
}
|
||||
@@ -74,4 +74,20 @@ int path_mkdir(const char *path, int mode)
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int path_mkdir_p(char *path, int mode)
|
||||
{
|
||||
char *ptr = path;
|
||||
int ret;
|
||||
|
||||
while ((ptr = strchr(ptr, '/'))) {
|
||||
*ptr = '\0';
|
||||
ret = path_mkdir(path, mode);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
*ptr = '/';
|
||||
ptr++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -23,6 +23,14 @@ const char *type_tostring(type t)
|
||||
}
|
||||
}
|
||||
|
||||
void av_dic_dump(AVDictionary *dic)
|
||||
{
|
||||
AVDictionaryEntry *entry = NULL;
|
||||
|
||||
while ((entry = av_dict_get(dic, "", entry, AV_DICT_IGNORE_SUFFIX)))
|
||||
printf("%s: %s\n", entry->key, entry->value);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user