[FFmpeg-devel] [PATCH 1/1] Output .lrc with correct end time
Lu Renjia
gusongcn at gmail.com
Wed Oct 23 10:50:54 EEST 2024
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
More information about the ffmpeg-devel
mailing list