Opened 22 months ago
Last modified 22 months ago
#11253 new defect
Generate .lrc from .sbv or .srt have end time error on some lines
| Reported by: | gusong | Owned by: | |
|---|---|---|---|
| Priority: | normal | Component: | avformat |
| Version: | git-master | Keywords: | lrc |
| Cc: | Blocked By: | ||
| Blocking: | Reproduced by developer: | no | |
| Analyzed by developer: | no |
Description
Summary of the bug:
FFmpeg generate .lrc file will show line time too long than defined.
How to reproduce:
input.sbv ==FILE BEGIN== 0:00:00.000,0:00:03.000 Title 0:00:10.000,0:00:15.000 Line 1 ==FILE END== % ffmpeg -i input.sbv output.lrc % cat output.lrc [re:Lavf61.7.100] [ve:61.7.100] [00:00.00]Title [00:10.00]Line 1 'Title' should show only 3 seconds, not 10 seconds, Expected output.lrc: ==FILE BEGIN== [re:Lavf61.9.100] [ve:61.9.100] [00:00.00]Title [00:03.00] [00:10.00]Line 1 ==FILE END== ffmpeg version 7.1 built on x86_64 MSYS2
Note:
See TracTickets
for help on using tickets.



Sorry I still not find the way email patch, this is a small one.
diff --git a/libavformat/lrcenc.c b/libavformat/lrcenc.c index 7570529..37380cf 100644 --- a/libavformat/lrcenc.c +++ b/libavformat/lrcenc.c @@ -33,10 +33,19 @@ #include "libavutil/log.h" #include "libavutil/macros.h" +typedef struct LrcContext { + /** + * Look ahead timestamp pts + duration + */ + int64_t lookahead_te; +} LrcContext; + static int lrc_write_header(AVFormatContext *s) { const AVDictionaryEntry *metadata_item; + LrcContext *lc = s->priv_data; + lc->lookahead_te = 0; if(s->streams[0]->codecpar->codec_id != AV_CODEC_ID_SUBRIP && s->streams[0]->codecpar->codec_id != AV_CODEC_ID_TEXT) { av_log(s, AV_LOG_ERROR, "Unsupported subtitle codec: %s\n", @@ -77,6 +86,7 @@ static int lrc_write_header(AVFormatContext *s) static int lrc_write_packet(AVFormatContext *s, AVPacket *pkt) { + LrcContext *lc = s->priv_data; if(pkt->pts != AV_NOPTS_VALUE) { const uint8_t *line = pkt->data; const uint8_t *end = pkt->data + pkt->size; @@ -91,6 +101,8 @@ static int lrc_write_packet(AVFormatContext *s, AVPacket *pkt) while(line) { const uint8_t *next_line = memchr(line, '\n', end - line); size_t size = end - line; + const int64_t te = lc->lookahead_te; + lc->lookahead_te = pkt->pts + pkt->duration; if (next_line) { size = next_line - line; @@ -103,6 +115,14 @@ static int lrc_write_packet(AVFormatContext *s, AVPacket *pkt) "Subtitle starts with '[', may cause problems with LRC format.\n"); } + /* Verify whether a blank line is required between the two lines */ + if (te < pkt->pts && pkt->pts - te >= 10) { + avio_printf(s->pb, "[%02"PRIu64":%02"PRIu64".%02"PRIu64"]\n", + (FFABS64U(te) / 6000), + ((FFABS64U(te) / 100) % 60), + (FFABS64U(te) % 100)); + } + /* Offset feature of LRC can easily make pts negative, * we just output it directly and let the player drop it. */ avio_write(s->pb, "[-", 1 + (pkt->pts < 0)); @@ -129,7 +149,7 @@ const FFOutputFormat ff_lrc_muxer = { .p.audio_codec = AV_CODEC_ID_NONE, .p.subtitle_codec = AV_CODEC_ID_SUBRIP, .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH, - .priv_data_size = 0, + .priv_data_size = sizeof(LrcContext), .write_header = lrc_write_header, .write_packet = lrc_write_packet, };