EXIF metadata for images

This commit is contained in:
simon 2019-11-09 15:18:44 -05:00
parent ea4fb7fa0d
commit e72fa1587b
3 changed files with 37 additions and 31 deletions

View File

@ -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 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 | `audio/*` | ffmpeg | - | yes, `jpeg` | ID3 tags |
`video/*` | ffmpeg | - | yes, `jpeg` | title, comment | `video/*` | ffmpeg | - | yes, `jpeg` | title, comment, artist |
`image/*` | ffmpeg | - | yes, `jpeg` | *planned* | `image/*` | ffmpeg | - | yes, `jpeg` | `EXIF:Artist`, `EXIF:ImageDescription` |
ttf,ttc,cff,woff,fnt,otf | Freetype2 | - | yes, `bmp` | Name & style | ttf,ttc,cff,woff,fnt,otf | Freetype2 | - | yes, `bmp` | Name & style |
`text/plain` | *(none)* | yes | no | - | `text/plain` | *(none)* | yes | no | - |
docx, xlsx, pptx | | *planned* | no | *planned* | docx, xlsx, pptx | | *planned* | no | *planned* |

View File

@ -10,7 +10,7 @@
#define EPILOG "Made by simon987 <me@simon987.net>. Released under GPL-3.0" #define EPILOG "Made by simon987 <me@simon987.net>. 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[] = { static const char *const usage[] = {
"sist2 scan [OPTION]... PATH", "sist2 scan [OPTION]... PATH",
"sist2 index [OPTION]... INDEX", "sist2 index [OPTION]... INDEX",

View File

@ -116,9 +116,9 @@ AVFrame *read_frame(AVFormatContext *pFormatCtx, AVCodecContext *decoder, int st
return frame; 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_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_line_t *meta_tag = malloc(sizeof(meta_line_t) + tex.dyn_buffer.cur); \
meta_tag->key = keyname; \ meta_tag->key = keyname; \
strcpy(meta_tag->strval, tex.dyn_buffer.buf); \ strcpy(meta_tag->strval, tex.dyn_buffer.buf); \
@ -151,30 +151,39 @@ void append_audio_meta(AVFormatContext *pFormatCtx, document_t *doc) {
} }
__always_inline __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)); if (is_video) {
meta_duration->key = MetaMediaDuration; meta_line_t *meta_duration = malloc(sizeof(meta_line_t));
meta_duration->longval = pFormatCtx->duration / AV_TIME_BASE; meta_duration->key = MetaMediaDuration;
APPEND_META(doc, meta_duration) meta_duration->longval = pFormatCtx->duration / AV_TIME_BASE;
APPEND_META(doc, meta_duration)
meta_line_t *meta_bitrate = malloc(sizeof(meta_line_t)); meta_line_t *meta_bitrate = malloc(sizeof(meta_line_t));
meta_bitrate->key = MetaMediaBitrate; meta_bitrate->key = MetaMediaBitrate;
meta_bitrate->longval = pFormatCtx->bit_rate; meta_bitrate->longval = pFormatCtx->bit_rate;
APPEND_META(doc, meta_bitrate) APPEND_META(doc, meta_bitrate)
}
AVDictionaryEntry *tag = NULL; AVDictionaryEntry *tag = NULL;
while ((tag = av_dict_get(pFormatCtx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { if (is_video) {
char key[32]; while ((tag = av_dict_get(pFormatCtx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
strncpy(key, tag->key, sizeof(key)); if (include_audio_tags && strcmp(tag->key, "title") == 0) {
APPEND_TAG_META(doc, tag, MetaTitle)
char *ptr = key; } else if (strcmp(tag->key, "comment") == 0) {
for (; *ptr; ++ptr) *ptr = (char) tolower(*ptr); APPEND_TAG_META(doc, tag, MetaContent)
} else if (include_audio_tags && strcmp(tag->key, "artist") == 0) {
if (strcmp(key, "title") == 0 && include_audio_tags) { APPEND_TAG_META(doc, tag, MetaArtist)
APPEND_TAG_META(doc, tag, MetaTitle) }
} else if (strcmp(key, "comment") == 0) { }
APPEND_TAG_META(doc, tag, MetaContent) } 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) { if (video_stream != -1) {
AVStream *stream = pFormatCtx->streams[video_stream]; 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) { if (stream->codecpar->width <= MIN_SIZE || stream->codecpar->height <= MIN_SIZE) {
avformat_close_input(&pFormatCtx); avformat_close_input(&pFormatCtx);
avformat_free_context(pFormatCtx); avformat_free_context(pFormatCtx);
@ -273,6 +277,8 @@ void parse_media(const char *filepath, document_t *doc) {
return; return;
} }
append_video_meta(pFormatCtx, frame, doc, audio_stream == -1, stream->nb_frames > 1);
// Scale frame // Scale frame
AVFrame *scaled_frame = scale_frame(decoder, frame, ScanCtx.tn_size); AVFrame *scaled_frame = scale_frame(decoder, frame, ScanCtx.tn_size);