3

I learned how to transcode MKV video to MP4 with HEVC (x265) video encoding to make the files smaller in a way that makes it all compatible with iOS. But while the process is great — and the compression is great with low file size — when I try to merge subtitles into one specific video, the resulting MP4 video I get a pile of errors out of FFmpeg like this:

[mp4 @ 0x7facb9002000] pts has no value
[mp4 @ 0x7facb9002000] Application provided duration: 3152805999 / timestamp: 3154741000 is out of range for mov/mp4 format

I am using macOS Mojave (10.15.2) with FFmpeg 4.2.1 installed via Homebrew, but the problem persists even if I download the nightly build (ffmpeg-4.2.1-macos64-static, 20191215-9fe0790) and use that binary instead of the Homebrew installed version.

The issue is I have this one video I have successfully converted to an MP4 with x264 video and AAC audio in the past and have been able to merge SRT subtitles as well into the resulting file without issue. But when I create an MP4 using HEVC (x265) video today from the same exact source, the SRT subtitle merge fails with those “pts has no value” and “is out of range for mov/mp4 format” errors.

This is the command I use to create the HEVC (x265) MP4 video from an MKV source:

ffmpeg -i input.mkv \
       -map_metadata -1 \
       -vf scale=-1:720 \
       -c:v libx265 -crf 20 -c:a aac -b:a 128k \
       -threads 4 \
       -tag:v hvc1 -sn \
       -map 0:0 -map 0:1 output_hevc.mp4 \
       ;

And this is the command have used successfully in the past to merge SRT subtitles into an existing MP4 without re-encoding:

ffmpeg -i output_hevc.mp4 \
       -i input.srt \
       -c:v copy -c:a copy \
       -c:s mov_text -metadata:s:s:0 language=eng \
       output_final.mp4 \
       ;

I think the issue might be that for about 50% of the video there are no subtitles; only in the second 50% of the video are subtitles needed.

The video in question is about 2 hours long. And for the first 50 or so minutes, there is no need for English subtitles. But around 50 minutes in, that is when the subtitles kick in.

So the subtitles in the SRT begin like this:

1
00:52:33,123 --> 00:52:50,123
It was a dark and stormy night…

But when I run the above FFmpeg command, the output is something like this; times a bit fudged for example’s puropose:

Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
  Stream #1:0 -> #0:2 (subrip (srt) -> mov_text (native))
Press [q] to stop, [?] for help
frame=25560 fps=0.0 q=-1.0 size=  304640kB time=00:52:00.00 bitrate= 791.7kbits/frame=50730 fps=50726 q=-1.0 size=  681984kB time=time=00:52:00.00 bitrate=1772.4kbit[mp4 @ 0x7facb9002000] Application provided duration: 3152137000 / timestamp: 3152137000 is out of range for mov/mp4 format
[mp4 @ 0x7facb9002000] pts has no value
[mp4 @ 0x7facb9002000] Application provided duration: 3152805999 / timestamp: 3154741000 is out of range for mov/mp4 format
[mp4 @ 0x7facb9002000] pts has no value
[mp4 @ 0x7facb9002000] Application provided duration: 3153246998 / timestamp: 3156809000 is out of range for mov/mp4 format
[mp4 @ 0x7facb9002000] pts has no value
[mp4 @ 0x7facb9002000] Application provided duration: 3154051997 / timestamp: 3159013000 is out of range for mov/mp4 format
[mp4 @ 0x7facb9002000] pts has no value
[mp4 @ 0x7facb9002000] Application provided duration: 3155556996 / timestamp: 3163817000 is out of range for mov/mp4 format

And tons of similar messages until, et voila! The merge ends, no subtitles are viewable and there is that.

This is driving me nuts! I mean if I use the same command, but specify a seeking time that begins at around the point where subtitles come in I actually see the subtitles on the 50% of the video that needs them:

ffmpeg -I output_hevc.mp4 \
       -i input.srt \
       -c:v copy -c:a copy \
       -c:s mov_text -metadata:s:s:0 language=eng \
       -ss 3120 \
       output_final.mp4 \
       ;

But I need more than 50% of the video, of course. Heck, I even just tried this command; I can get the subtitles to merge with the MP4 if I set the seeking to any value equal or greater than 1005 seconds:

ffmpeg -i output_hevc.mp4 \
       -i input.srt \
       -c:v copy -c:a copy \
       -c:s mov_text -metadata:s:s:0 language=eng \
       -ss 1005 \
       output_final.mp4 \
       ;

But what is so magical about 16.75 minutes (1005 seconds) in the context of this?

Why can I get the subtitles to be merged if I only select the times the subtitles appear in the second 50% of the video but not if I run the command to merge the full video?

FWIW, if I run a similar command to create an MKV of the video, all is fine!

ffmpeg -i output_hevc.mp4 \
       -i input.srt \
       -c:v copy -c:a copy -c:s copy \
       output.mkv \
       ;

Just somehow this merging with mov_text makes the process fail it seems.

And if I add a bogus subtitle at the beginning of the file like this:

0
00:00:00,000 --> 00:16:75,000
Foo!

1
00:52:33,123 --> 00:52:50,123
It was a dark and stormy night…

Everything works as desired! Except for having the word “Foo!” showing up for 50% of the video. Obviously not ideal.

Is there any way around this? Is this an FFmpeg bug or perhaps an issue with HEVC (x265) video with subtitles being merged?

2 Answers 2

2

Seems like adding a bogus subtitle at the beginning of the SRT file that spans from the beginning of the video to about where the subtitles begin fixed this issue.

This solution is clearly a “hack” but it works.

Riding off of my idea to add a bogus subtitle at the beginning of the SRT file, I realized that SRT subtitles — according to the SRT specs — allow for HTML tags. Knowing that I added the following bogus subtitle and it all works!

0
00:00:00,000 --> 00:16:75,000
<b></b>

1
00:52:33,123 --> 00:52:50,123
It was a dark and stormy night…

That’s it! Just adding an empty bold tag allows it all to work and for the subtitles to be merged…


But — as stated at the outset — this is clearly a hack and I am open to hearing more from others who know more about FFmpeg. I can only assume none of this issue reflects desired behavior and there must be a more elegant way to deal with cases like this. Or is this a bug (not a feature) and should be reported?

0
1

I had this exact issue with a media file I am working with and I spent the better part of a day trying different commands, and different ways of rebuilding the pts all to no avail before I finally stumbled on this post. To my great sadness the proposed workaround here did not work for me.

I am running on Windows 11 using the binaries compiled for Windows by gyan.dev, however I have also tried the same commands through WSL (Windows Subsystem for Linux) running ubuntu and installing via apt.

When inserting the empty tags I continued to get the same errors:

0
00:00:00,000 --> 00:18:00,000
<b></b>

1
00:43:21,472 --> 00:43:24,933
Mysterious translated text here

[mp4 @ 0000023630f5cf80] Packet duration: 2601472000 / dts: 2601472000 is out of range
[mp4 @ 0000023630f5cf80] pts has no value
[mp4 @ 0000023630f5cf80] Packet duration: 2601681999 / dts: 2605143000 is out of range
[mp4 @ 0000023630f5cf80] pts has no value
[mp4 @ 0000023630f5cf80] Packet duration: 2602474998 / dts: 2608605000 is out of range
[mp4 @ 0000023630f5cf80] pts has no value
[mp4 @ 0000023630f5cf80] Packet duration: 2603642997 / dts: 2611441000 is out of range
[mp4 @ 0000023630f5cf80] pts has no value

If I instead inserted a single visible character such as a single period, then the srt file would merge without issues. Of course I would then be stuck with a period on the screen for the first 40ish minutes of my video.

0
00:00:00,000 --> 00:18:00,000
.

1
00:43:21,472 --> 00:43:24,933
Mysterious translated text here

I tried with the bold tag, italics tag, and any other tag I could think of even the paragraph tag which isn't recognized. Any empty tags would not trigger the time to be kept and result in the 'pts has no value' errors.

In desperation I decided to use a quantity over quality approach by adding 10 entries spaced 2 minutes apart with a very low duration so instead of a solid visible period character I would have an intermittent one and that worked. So on a whim I tried to set the start time and the end time of the first 10 entries to be the same and that resulted in the period character being hidden and the subtitle merging in without error:

1
00:02:00,000 --> 00:02:00,000
.

2
00:04:00,000 --> 00:04:00,000
.

3
00:06:00,000 --> 00:06:00,000
.

4
00:08:00,000 --> 00:08:00,000
.

5
00:10:00,000 --> 00:10:00,000
.

6
00:12:00,000 --> 00:12:00,000
.

7
00:14:00,000 --> 00:14:00,000
.

8
00:16:00,000 --> 00:16:00,000
.

9
00:18:00,000 --> 00:18:00,000
.

10
00:20:01,000 --> 00:20:01,000
.

11
00:43:21,472 --> 00:43:24,933
Mysterious translated text here

Like the original post here this is a hacky workaround and not a proper solution, but also like the original post here I could not find a proper solution. Hopefully this helps anyone else who has this issue and stumbles upon this post like I did.

If you have a large srt that you dread having to increment by hand, I had GPT whip up this little Python script for me (I could have written it myself, but I was all but done fighting this problem at this point and figured it was simple enough for GPT to handle)

def add_entries_to_srt(existing_file_path, new_file_path, num_entries=10, duration=0.1, buffer_time=120):
    with open(existing_file_path, 'r', encoding='utf-8') as existing_file:
        existing_content = existing_file.read()

    # Parse existing entries
    entries = existing_content.strip().split('\n\n')
    existing_entries_count = len(entries)

    # Generate new entries
    new_entries = []
    for i in range(1, num_entries + 1):
        start_time = i * (duration + buffer_time)
        end_time = start_time + duration
        entry_text = f"{i}\n{format_time(start_time)} --> {format_time(end_time)}\n<i>.</i>"
        new_entries.append(entry_text)

    # Increment entry numbers of existing entries
    for i in range(existing_entries_count):
        entry_lines = entries[i].split('\n')
        entry_number = int(entry_lines[0])
        entry_lines[0] = str(entry_number + num_entries)
        entries[i] = '\n'.join(entry_lines)

    # Combine new and existing entries
    combined_entries = '\n\n'.join(new_entries + entries)

    # Write to the new file
    with open(new_file_path, 'w', encoding='utf-8') as new_file:
        new_file.write(combined_entries)

def format_time(seconds):
    minutes, seconds = divmod(seconds, 60)
    hours, minutes = divmod(minutes, 60)
    return f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d},000"

# Replace 'existing_subtitle.srt' with your actual file path
existing_file_path = r'C:\Temp\ffmpeg\Subtitles.srt'
new_file_path = r'C:\Temp\ffmpeg\Subtitles.EDIT.srt'

add_entries_to_srt(existing_file_path, new_file_path)

EDIT: It turns out that depending on your player, setting the start and end time of the first 10 entries the same results in the period either being hidden, or visible for 5 seconds. Setting an offset of 1 millisecond appears to be much more reliable at keeping the period hidden.

1
00:02:00,000 --> 00:02:00,001
.

2
00:04:00,000 --> 00:04:00,001
.

3
00:06:00,000 --> 00:06:00,001
.

4
00:08:00,000 --> 00:08:00,001
.

5
00:10:00,000 --> 00:10:00,001
.

6
00:12:00,000 --> 00:12:00,001
.

7
00:14:00,000 --> 00:14:00,001
.

8
00:16:00,000 --> 00:16:00,001
.

9
00:18:00,000 --> 00:18:00,001
.

10
00:20:01,000 --> 00:20:01,001
.

11
00:43:21,472 --> 00:43:24,933
Mysterious translated text here
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .