Skip to content
Fondazione ITS INCOM

Examples · Programming

Subtitles from a recording, in Python

Transcribe a recording with the time of every sentence, and write an .srt file that VLC, YouTube and video editors can read.

Intermediate · 35 min

What you need

A key and the openai library, as in Your first API call in Python, and a recording: a voice memo from your phone, an MP3, a WAV or a short video, up to 25 MB.

No recording at hand? Let a voice of the school make one. Save it as make_test.py:

import os

from openai import OpenAI

client = OpenAI(
    base_url="https://api.ai.itsincom.org/v1",
    api_key=os.environ["API_KEY"],
)

talk = ("Good morning, everyone. Today we present our project for the Internet of Things course. "
        "We built a weather station with a Raspberry Pi and three sensors. "
        "Every five minutes it measures the temperature, the humidity and the air pressure. "
        "The readings go to a database in the cloud, and a web page draws the charts. "
        "Thank you for listening.")

speech = client.audio.speech.create(model="tts-1", voice="ryan", input=talk, response_format="mp3")
speech.write_to_file("talk.mp3")
print("talk.mp3 is ready")

The model

Two models transcribe: whisper-1, the faster, and whisper-1-hd, the more accurate. Subtitles are read word by word, so this program uses whisper-1-hd.

The program

Save it as subtitles.py:

import os
import sys

from openai import OpenAI

client = OpenAI(
    base_url="https://api.ai.itsincom.org/v1",
    api_key=os.environ["API_KEY"],
)


def stamp(seconds):
    """12.5 -> 00:00:12,500, the way SRT writes a time."""
    ms = round(seconds * 1000)
    return f"{ms // 3600000:02}:{ms // 60000 % 60:02}:{ms // 1000 % 60:02},{ms % 1000:03}"


path = sys.argv[1]
with open(path, "rb") as f:
    result = client.audio.transcriptions.create(
        model="whisper-1-hd",
        file=f,
        language="en",
        response_format="verbose_json",
        timestamp_granularities=["segment", "word"],
    )

srt_path = os.path.splitext(path)[0] + ".srt"
with open(srt_path, "w", encoding="utf-8") as srt:
    for n, segment in enumerate(result.segments, 1):
        srt.write(f"{n}\n{stamp(segment.start)} --> {stamp(segment.end)}\n{segment.text.strip()}\n\n")

print(f"{len(result.segments)} subtitles in {srt_path}, {result.duration:.0f} seconds of audio")

Run it on your recording:

python3 subtitles.py talk.mp3

What you should see

10 subtitles in talk.srt, 17 seconds of audio

and talk.srt begins like this:

1
00:00:00,000 --> 00:00:00,960
Good morning, everyone.

2
00:00:01,340 --> 00:00:03,000
Today, we present our project

3
00:00:03,000 --> 00:00:04,480
for the Internet of Things course.

Every take of a voice is a little different, so your times will not be exactly these. When we ran it, subtitle 4 said “We built the weather station”, where the voice read “a weather station”: a small thing, but it is why you read subtitles before you publish them.

How it works

Good to know

Exercise

All examples