Probleme beim Zusammenführen von SRT-Untertiteln mit einer für iOS transkodierten MP4-Datei (HEVC/x265/mov_text): „pts hat keinen Wert“ und „liegt außerhalb des Bereichs für das mov/mp4-Format“

Probleme beim Zusammenführen von SRT-Untertiteln mit einer für iOS transkodierten MP4-Datei (HEVC/x265/mov_text): „pts hat keinen Wert“ und „liegt außerhalb des Bereichs für das mov/mp4-Format“

Ich habe gelernt, wie man MKV-Videos mit HEVC-Videocodierung (x265) in MP4 umwandelt, um die Dateien so zu verkleinern, dass sie mit iOS kompatibel sind. Aber obwohl der Vorgang großartig ist – und die Komprimierung bei geringer Dateigröße großartig ist –, erhalte ich beim Versuch, Untertitel in ein bestimmtes Video einzufügen, im resultierenden MP4-Video einen Haufen Fehler von FFmpeg wie diesen:

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

Ich verwende macOS Mojave (10.15.2) mit FFmpeg 4.2.1, das über Homebrew installiert wurde, aber das Problem besteht weiterhin, auch wenn ich dienächtlich gebaut(ffmpeg-4.2.1-macos64-static, 20191215-9fe0790) und verwenden Sie diese Binärdatei anstelle der installierten Homebrew-Version.

Das Problem ist, dass ich dieses eine Video in der Vergangenheit erfolgreich in ein MP4 mit x264-Video und AAC-Audio konvertiert habe und auch SRT-Untertitel problemlos in die resultierende Datei einfügen konnte. Aber wenn ich heute ein MP4 mit HEVC-Video (x265) aus genau derselben Quelle erstelle, schlägt die Zusammenführung der SRT-Untertitel mit den Fehlermeldungen „pts hat keinen Wert“ und „liegt außerhalb des Bereichs für das MOV/MP4-Format“ fehl.

Dies ist der Befehl, den ich verwende, um das HEVC (x265) MP4-Video aus einer MKV-Quelle zu erstellen:

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 \
       ;

Und dies ist der Befehl, den ich in der Vergangenheit erfolgreich verwendet habe, um SRT-Untertitel ohne erneute Kodierung in eine vorhandene MP4-Datei einzufügen:

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 \
       ;

Ich denke, das Problem könnte darin liegen, dass für etwa 50 % des Videos keine Untertitel vorhanden sind; nur für die zweiten 50 % des Videos werden Untertitel benötigt.

Das fragliche Video ist etwa 2 Stunden lang. Und in den ersten 50 Minuten sind keine englischen Untertitel erforderlich. Aber nach etwa 50 Minuten beginnen die Untertitel.

Die Untertitel im SRT beginnen also folgendermaßen:

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

Aber wenn ich den obigen FFmpeg-Befehl ausführe, sieht die Ausgabe ungefähr so ​​aus (mal ein bisschen gefälscht, um das Beispiel zu verdeutlichen):

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

Und jede Menge ähnlicher Nachrichten, bis, et voila! Die Zusammenführung endet, es sind keine Untertitel mehr sichtbar und das war’s.

Das macht mich wahnsinnig! Ich meine, wenn ich denselben Befehl verwende, aber eine Suchzeit angebe, die ungefähr an der Stelle beginnt, an der die Untertitel kommen, sehe ich die Untertitel tatsächlich in den 50 % des Videos, die sie benötigen:

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 \
       ;

Aber ich brauche natürlich mehr als 50 % des Videos. Ich habe sogar gerade diesen Befehl ausprobiert. Ich kann die Untertitel mit der MP4-Datei verschmelzen, wenn ich die Suche auf einen Wert gleich oder größer als 1005 Sekunden einstelle:

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 \
       ;

Doch was ist in diesem Zusammenhang das Magische an 16,75 Minuten (1005 Sekunden)?

Warum können die Untertitel zusammengeführt werden, wenn ich nur die Stellen auswähle, an denen die Untertitel in der zweiten Hälfte des Videos erscheinen sollen, nicht jedoch, wenn ich den Befehl zum Zusammenführen des gesamten Videos ausführe?

Wenn ich einen ähnlichen Befehl ausführe, um eine MKV-Datei des Videos zu erstellen, ist alles in Ordnung!

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

Es scheint , dass diese Verschmelzung mov_textden Prozess irgendwie zum Scheitern bringt.

Und wenn ich am Anfang der Datei einen falschen Untertitel hinzufüge, wie diesen:

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…

Alles funktioniert wie gewünscht! Außer, dass das Wort „Foo!“ bei 50 % des Videos angezeigt wird. Offensichtlich nicht ideal.

Gibt es eine Möglichkeit, das zu umgehen? Handelt es sich hierbei um einen FFmpeg-Fehler oder vielleicht um ein Problem mit HEVC-Videos (x265), bei denen Untertitel zusammengeführt werden?

Antwort1

Dieses Problem scheint dadurch behoben worden zu sein, dass am Anfang der SRT-Datei ein falscher Untertitel hinzugefügt wird, der sich vom Anfang des Videos bis etwa zu der Stelle erstreckt, an der die Untertitel beginnen.

Diese Lösung ist eindeutig ein „Hack“, aber sie funktioniert.

Als ich von meiner Idee ausging, einen falschen Untertitel am Anfang der SRT-Datei einzufügen, wurde mir klar, dass SRT-Untertitel — lautdie SRT-Spezifikationen— HTML-Tags zulassen. Da ich das wusste, habe ich den folgenden falschen Untertitel hinzugefügt und alles funktioniert!

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…

Das ist alles! Durch das Hinzufügen eines leeren Fettschrift-Tags funktioniert alles und die Untertitel werden zusammengeführt …


Aber – wie eingangs erwähnt – ist dies eindeutig ein Hack und ich bin offen dafür, mehr von anderen zu hören, die mehr über FFmpeg wissen. Ich kann nur davon ausgehen, dass keines dieser Probleme das gewünschte Verhalten widerspiegelt und es einen eleganteren Weg geben muss, mit Fällen wie diesem umzugehen. Oder ist dies ein Fehler (keine Funktion) und sollte gemeldet werden?

Antwort2

Ich hatte genau dieses Problem mit einer Mediendatei, mit der ich arbeite, und habe fast einen ganzen Tag damit verbracht, verschiedene Befehle und verschiedene Möglichkeiten zum Wiederherstellen der Punkte auszuprobieren, alles ohne Erfolg, bis ich schließlich auf diesen Beitrag gestoßen bin. Zu meinem großen Bedauern hat die hier vorgeschlagene Problemumgehung bei mir nicht funktioniert.

Ich verwende Windows 11 und verwende die von gyan.dev für Windows kompilierten Binärdateien, habe jedoch dieselben Befehle auch über WSL (Windows-Subsystem für Linux) ausprobiert, indem ich Ubuntu ausgeführt und die Installation über apt durchgeführt habe.

Beim Einfügen der leeren Tags erhielt ich weiterhin die gleichen Fehler:

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

Wenn ich stattdessen ein einzelnes sichtbares Zeichen wie einen einzelnen Punkt einfügen würde, würde die SRT-Datei problemlos zusammengeführt. Natürlich würde ich dann in den ersten 40 Minuten meines Videos mit einem Punkt auf dem Bildschirm festhängen.

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

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

Ich habe es mit dem Fettdruck-Tag, dem Kursivdruck-Tag und jedem anderen Tag versucht, der mir eingefallen ist, sogar mit dem Absatz-Tag, der nicht erkannt wird. Leere Tags würden die Zeit nicht speichern und zu den Fehlern „Punkte haben keinen Wert“ führen.

In meiner Verzweiflung entschied ich mich für einen Ansatz, bei dem Quantität vor Qualität stand. Dazu fügte ich 10 Einträge mit einem Abstand von 2 Minuten und sehr kurzer Dauer hinzu, sodass ich statt eines durchgehend sichtbaren Punktzeichens ein intermittierendes hatte, und das funktionierte. Also versuchte ich aus einer Laune heraus, die Start- und Endzeit der ersten 10 Einträge gleich zu setzen, und das führte dazu, dass das Punktzeichen ausgeblendet und der Untertitel ohne Fehler eingefügt wurde:

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

Wie der Originalbeitrag hier ist dies ein Hack-Workaround und keine richtige Lösung, aber wie der Originalbeitrag hier konnte ich auch keine richtige Lösung finden. Hoffentlich hilft dies jedem anderen, der dieses Problem hat und wie ich auf diesen Beitrag stößt.

Wenn Sie über ein großes SRT verfügen und es nicht gerne von Hand erhöhen möchten, habe ich GPT dieses kleine Python-Skript für mich erstellen lassen (ich hätte es auch selbst schreiben können, aber zu diesem Zeitpunkt hatte ich den Kampf gegen dieses Problem fast schon satt und dachte, es wäre einfach genug, damit GPT damit umgehen könnte).

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)

BEARBEITEN: Es hat sich herausgestellt, dass je nach Player das gleiche Einstellen der Start- und Endzeit der ersten 10 Einträge dazu führt, dass der Zeitraum entweder ausgeblendet oder 5 Sekunden lang sichtbar bleibt. Das Einstellen eines Offsets von 1 Millisekunde scheint viel zuverlässiger zu sein, um den Zeitraum ausgeblendet zu halten.

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

verwandte Informationen