Cleaning up attachment management

This commit is contained in:
Zoe Roux
2021-03-19 17:12:51 +01:00
parent 00abdd86f6
commit db2541af52
8 changed files with 67 additions and 36 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}

View File

@@ -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)
{