From 0a849fc1d9bcdd9442a963aa5383ed59c47b07c8 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Sun, 9 Mar 2025 20:06:41 -0700 Subject: [PATCH] FFmpeg: Handle multiple attached pictures properly Now it handles multiple attached pictures and tries to pick out the one which may be the front cover picture, or otherwise picks the first one. Signed-off-by: Christopher Snowhill --- Plugins/FFMPEG/FFMPEGDecoder.m | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/Plugins/FFMPEG/FFMPEGDecoder.m b/Plugins/FFMPEG/FFMPEGDecoder.m index c92ef0641..6ebf59318 100644 --- a/Plugins/FFMPEG/FFMPEGDecoder.m +++ b/Plugins/FFMPEG/FFMPEGDecoder.m @@ -192,6 +192,8 @@ static uint8_t reverse_bits[0x100]; attachedPicIndex = -1; AVCodecParameters *codecPar; + NSMutableArray *pictures = [[NSMutableArray alloc] init]; + for(i = 0; i < formatCtx->nb_streams; i++) { stream = formatCtx->streams[i]; codecPar = stream->codecpar; @@ -201,7 +203,7 @@ static uint8_t reverse_bits[0x100]; } else if(codecPar->codec_id == AV_CODEC_ID_TIMED_ID3) { metadataIndex = i; } else if(stream->disposition & AV_DISPOSITION_ATTACHED_PIC) { - attachedPicIndex = i; + [pictures addObject:@(i)]; } else { stream->discard = AVDISCARD_ALL; } @@ -212,6 +214,31 @@ static uint8_t reverse_bits[0x100]; return NO; } + if([pictures count]) { + if([pictures count] == 1) { + attachedPicIndex = [pictures[0] intValue]; + } else { + // Find the first attached picture with "front" or "cover" in its filename + for(NSNumber *picture in pictures) { + i = [picture intValue]; + stream = formatCtx->streams[i]; + AVDictionary *metadata = stream->metadata; + AVDictionaryEntry *filename = av_dict_get(metadata, "filename", NULL, 0); + if(filename) { + if(strcasestr(filename->value, "front") || + strcasestr(filename->value, "cover")) { + attachedPicIndex = i; + break; + } + } + } + // Or else find the first attached picture + if(attachedPicIndex < 0) { + attachedPicIndex = [pictures[0] intValue]; + } + } + } + stream = formatCtx->streams[streamIndex]; codecPar = stream->codecpar;