When input .sbv or .srt and output .lrc, line end time is incorrect as condition below: $ cat > input.sbv << EOF 0:00:00.000,0:00:03.000 Title
0:00:10.000,0:00:15.000 Line 1 EOF $ ffmpeg -i input.sbv out.lrc $ cat out.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 out.lrc should be: ======== [00:00.00]Title [00:03.00] [00:10.00]Line 1 ======== Fix "Generate .lrc from .sbv or .srt have end time error on some lines" https://trac.ffmpeg.org/ticket/11253 --- libavformat/lrcenc.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) 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, }; -- 2.47.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".