Wyciąganie napisów z filmu

Przykład wyciągania napisów z filmu:

$ ffprobe -loglevel error -select_streams s -show_entries stream=index:stream_tags=language,title -of compact <movie.mp4>
stream|index=2|tag:language=eng
stream|index=3|tag:language=fre

Wyciągniecie napisów z filmu:

$ ffmpeg -i <movie.mp4> -map 0:2 <subs.srt>  # w przykładzie 2 do index

Skrypt

Gotowy do użycia skrypt Bash, który automatycznie wykrywa wszystkie ścieżki napisów w filmie i eksportuje je do osobnych plików .srt, nazywając je zgodnie z kodem języka (np. film_eng.srt, film_pol.srt).

Gotowy skrypt Bash (extract_subtitles.sh)

#!/bin/bash

# Sprawdzenie, czy podano plik wejściowy
if [ -z "$1" ]; then
    echo "Użycie: $0 <plik_wideo>"
    exit 1
fi

INPUT_FILE="$1"
# Pobranie nazwy pliku bez rozszerzenia
BASE_NAME="${INPUT_FILE%.*}"

# Pobranie listy strumieni napisów (indeks i język) za pomocą ffprobe
# Format wyjściowy: indeks:język (np. 2:eng)
streams=$(ffprobe -loglevel error -select_streams s -show_entries stream=index:stream_tags=language -of csv=p=0 "$INPUT_FILE")

if [ -z "$streams" ]; then
    echo "Nie znaleziono żadnych strumieni napisów w pliku $INPUT_FILE."
    exit 1
fi

# Przetwarzanie każdego strumienia
echo "$streams" | while IFS=, read -r index lang; do
    # Jeśli język nie jest określony w metadanych, ustaw domyślny tekst "unknown"
    if [ -z "$lang" ]; then
        lang="unknown_${index}"
    fi

    OUTPUT_FILE="${BASE_NAME}_${lang}.srt"
    
    echo "Eksportowanie strumienia #$index (język: $lang) do pliku $OUTPUT_FILE..."
    
    # Wyciąganie napisów i wymuszenie formatu SRT (-f srt)
    ffmpeg -loglevel error -y -i "$INPUT_FILE" -map 0:"$index" -f srt "$OUTPUT_FILE"
done

echo "Gotowe! Wszystkie napisy zostały wyeksportowane."

Jak to działa?

  • Skrypt używa ffprobe, aby pobrać pary indeks,język dla każdego strumienia napisów.
  • Pętla while przetwarza każdą linię osobno.
  • Jeśli plik wideo nie ma zdefiniowanego języka w metadanych, skrypt automatycznie nazwie plik końcówką _unknown_X.srt (gdzie X to numer strumienia), aby pliki się nie nadpisywały.
  • Flaga -f srt w poleceniu ffmpeg wymusza konwersję do formatu SRT, nawet jeśli wewnętrzny format w filmie był inny (np. mov_text czy ass).