From e72fa1587b6b0ea50bbaf899493b3ae9641a68ac Mon Sep 17 00:00:00 2001 From: simon Date: Sat, 9 Nov 2019 15:18:44 -0500 Subject: [PATCH] EXIF metadata for images --- README.md | 6 ++--- src/main.c | 2 +- src/parsing/media.c | 60 +++++++++++++++++++++++++-------------------- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index b67b55d..9baa3b3 100644 --- a/README.md +++ b/README.md @@ -56,10 +56,10 @@ sist2 web --bind 0.0.0.0 --port 4321 ./my_idx1 ./my_idx2 ./my_idx3 File type | Library | Content | Thumbnail | Metadata :---|:---|:---|:---|:--- -pdf,xps,cbz,cbr,fb2,epub | MuPDF | yes | yes, `png` | title | +pdf,xps,cbz,fb2,epub | MuPDF | yes | yes, `png` | title | `audio/*` | ffmpeg | - | yes, `jpeg` | ID3 tags | -`video/*` | ffmpeg | - | yes, `jpeg` | title, comment | -`image/*` | ffmpeg | - | yes, `jpeg` | *planned* | +`video/*` | ffmpeg | - | yes, `jpeg` | title, comment, artist | +`image/*` | ffmpeg | - | yes, `jpeg` | `EXIF:Artist`, `EXIF:ImageDescription` | ttf,ttc,cff,woff,fnt,otf | Freetype2 | - | yes, `bmp` | Name & style | `text/plain` | *(none)* | yes | no | - | docx, xlsx, pptx | | *planned* | no | *planned* | diff --git a/src/main.c b/src/main.c index 632a3b4..675154b 100644 --- a/src/main.c +++ b/src/main.c @@ -10,7 +10,7 @@ #define EPILOG "Made by simon987 . Released under GPL-3.0" -static const char *const Version = "1.1.2"; +static const char *const Version = "1.1.3"; static const char *const usage[] = { "sist2 scan [OPTION]... PATH", "sist2 index [OPTION]... INDEX", diff --git a/src/parsing/media.c b/src/parsing/media.c index ad95bca..572686e 100644 --- a/src/parsing/media.c +++ b/src/parsing/media.c @@ -116,9 +116,9 @@ AVFrame *read_frame(AVFormatContext *pFormatCtx, AVCodecContext *decoder, int st return frame; } -#define APPEND_TAG_META(doc, tag, keyname) \ +#define APPEND_TAG_META(doc, tag_, keyname) \ text_buffer_t tex = text_buffer_create(-1); \ - text_buffer_append_string0(&tex, tag->value); \ + text_buffer_append_string0(&tex, tag_->value); \ meta_line_t *meta_tag = malloc(sizeof(meta_line_t) + tex.dyn_buffer.cur); \ meta_tag->key = keyname; \ strcpy(meta_tag->strval, tex.dyn_buffer.buf); \ @@ -151,30 +151,39 @@ void append_audio_meta(AVFormatContext *pFormatCtx, document_t *doc) { } __always_inline -void append_video_meta(AVFormatContext *pFormatCtx, document_t *doc, int include_audio_tags) { +void append_video_meta(AVFormatContext *pFormatCtx, AVFrame *frame, document_t *doc, int include_audio_tags, int is_video) { - meta_line_t *meta_duration = malloc(sizeof(meta_line_t)); - meta_duration->key = MetaMediaDuration; - meta_duration->longval = pFormatCtx->duration / AV_TIME_BASE; - APPEND_META(doc, meta_duration) + if (is_video) { + meta_line_t *meta_duration = malloc(sizeof(meta_line_t)); + meta_duration->key = MetaMediaDuration; + meta_duration->longval = pFormatCtx->duration / AV_TIME_BASE; + APPEND_META(doc, meta_duration) - meta_line_t *meta_bitrate = malloc(sizeof(meta_line_t)); - meta_bitrate->key = MetaMediaBitrate; - meta_bitrate->longval = pFormatCtx->bit_rate; - APPEND_META(doc, meta_bitrate) + meta_line_t *meta_bitrate = malloc(sizeof(meta_line_t)); + meta_bitrate->key = MetaMediaBitrate; + meta_bitrate->longval = pFormatCtx->bit_rate; + APPEND_META(doc, meta_bitrate) + } AVDictionaryEntry *tag = NULL; - while ((tag = av_dict_get(pFormatCtx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { - char key[32]; - strncpy(key, tag->key, sizeof(key)); - - char *ptr = key; - for (; *ptr; ++ptr) *ptr = (char) tolower(*ptr); - - if (strcmp(key, "title") == 0 && include_audio_tags) { - APPEND_TAG_META(doc, tag, MetaTitle) - } else if (strcmp(key, "comment") == 0) { - APPEND_TAG_META(doc, tag, MetaContent) + if (is_video) { + while ((tag = av_dict_get(pFormatCtx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + if (include_audio_tags && strcmp(tag->key, "title") == 0) { + APPEND_TAG_META(doc, tag, MetaTitle) + } else if (strcmp(tag->key, "comment") == 0) { + APPEND_TAG_META(doc, tag, MetaContent) + } else if (include_audio_tags && strcmp(tag->key, "artist") == 0) { + APPEND_TAG_META(doc, tag, MetaArtist) + } + } + } else { + // EXIF metadata + while ((tag = av_dict_get(frame->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + if (include_audio_tags && strcmp(tag->key, "Artist") == 0) { + APPEND_TAG_META(doc, tag, MetaArtist) + } else if (strcmp(tag->key, "ImageDescription") == 0) { + APPEND_TAG_META(doc, tag, MetaContent) + } } } } @@ -236,11 +245,6 @@ void parse_media(const char *filepath, document_t *doc) { if (video_stream != -1) { AVStream *stream = pFormatCtx->streams[video_stream]; - if (stream->nb_frames > 1) { - //This is a video (not a still image) - append_video_meta(pFormatCtx, doc, audio_stream == -1); - } - if (stream->codecpar->width <= MIN_SIZE || stream->codecpar->height <= MIN_SIZE) { avformat_close_input(&pFormatCtx); avformat_free_context(pFormatCtx); @@ -273,6 +277,8 @@ void parse_media(const char *filepath, document_t *doc) { return; } + append_video_meta(pFormatCtx, frame, doc, audio_stream == -1, stream->nb_frames > 1); + // Scale frame AVFrame *scaled_frame = scale_frame(decoder, frame, ScanCtx.tn_size);