diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 4d73788143..3806a12ca2 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -307,6 +307,11 @@ input until the timestamps reach @var{position}. @var{position} may be either in seconds or in @code{hh:mm:ss[.xxx]} form. +@item -sseof @var{position} (@emph{input/output}) + +Like the -ss option but relative to the "end of file". That is negative +values are earlier in the file, 0 is at EOF. + @item -itsoffset @var{offset} (@emph{input}) Set the input time offset. diff --git a/ffmpeg.h b/ffmpeg.h index a7e5e51140..7467b165f8 100644 --- a/ffmpeg.h +++ b/ffmpeg.h @@ -92,6 +92,7 @@ typedef struct OptionsContext { /* input/output options */ int64_t start_time; + int64_t start_time_eof; int seek_timestamp; const char *format; diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index 3c9f98af81..351c47bf42 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -156,6 +156,7 @@ static void init_options(OptionsContext *o) o->stop_time = INT64_MAX; o->mux_max_delay = 0.7; o->start_time = AV_NOPTS_VALUE; + o->start_time_eof = AV_NOPTS_VALUE; o->recording_time = INT64_MAX; o->limit_filesize = UINT64_MAX; o->chapters_input_file = INT_MAX; @@ -933,6 +934,8 @@ static int open_input_file(OptionsContext *o, const char *filename) } } + if (o->start_time_eof != AV_NOPTS_VALUE && ic->duration>0) + o->start_time = o->start_time_eof + ic->duration; timestamp = (o->start_time == AV_NOPTS_VALUE) ? 0 : o->start_time; /* add the stream start time */ if (!o->seek_timestamp && ic->start_time != AV_NOPTS_VALUE) @@ -3019,6 +3022,9 @@ const OptionDef options[] = { { "ss", HAS_ARG | OPT_TIME | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(start_time) }, "set the start time offset", "time_off" }, + { "sseof", HAS_ARG | OPT_TIME | OPT_OFFSET | + OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(start_time_eof) }, + "set the start time offset relative to EOF", "time_off" }, { "seek_timestamp", HAS_ARG | OPT_INT | OPT_OFFSET | OPT_INPUT, { .off = OFFSET(seek_timestamp) }, "enable/disable seeking by timestamp with -ss" },