Erstellen Sie adaptive Streaming-Medienpakete (DASH & HLS) mit DRM-Unterstützung mithilfe von FFmpeg in Python
DASH & HLS-Unterstützung mit automatischer Bitraten-Anpassung
Diese Bibliothek nutzt FFmpeg, um Medienpakete zu erstellen, die mit Online-Streaming-Protokollen wie DASH (Dynamic Adaptive Streaming over HTTP) und HLS (HTTP Live Streaming) kompatibel sind. Sie bietet auch Funktionen für DRM (Digital Rights Management) für HLS-Packaging und die Verwaltung von Dateien, die in Cloud-Speichern gespeichert sind.
Erstellen Sie DASH- und HLS-Streams mit mehreren Bitraten-Darstellungen
AES-128-Verschlüsselung für HLS mit Schlüsselrotationsoptionen
Direkte Integration mit S3, Google Cloud, Azure und mehr
Unterstützung für Live-Streaming von Webcams und Bildschirmaufnahmen
Diese Bibliothek erfordert eine funktionierende FFmpeg-Installation, einschließlich der Binärdateien von FFMpeg und FFProbe.
Kompatibilität: Diese Bibliothek ist nur mit Python 3.9 oder höher kompatibel.
Mit pip:
pip install python-ffmpeg-video-streaming
Alternativ können Sie die Abhängigkeit zu Ihrer requirements.txt-Datei hinzufügen:
python-ffmpeg-video-streaming>=0.1
import ffmpeg_streaming
Es gibt mehrere Möglichkeiten, eine Medienressource zu öffnen:
video = ffmpeg_streaming.input('/var/media/video.mp4')
video = ffmpeg_streaming.input('https://www.quasarstream.com/?"PATH TO A VIDEO FILE" or "PATH TO A LIVE HTTP STREAM"')
Sie können eine Datei aus einer Cloud öffnen, indem Sie eine Instanz des Cloud-Objekts an die input
-Methode übergeben.
from ffmpeg_streaming import S3
s3 = S3(aws_access_key_id='YOUR_KEY_ID', aws_secret_access_key='YOUR_KEY_SECRET', region_name='YOUR_REGION')
video = ffmpeg_streaming.input(s3, bucket_name="bucket-name", key="video.mp4")
Sie können den Namen eines unterstützten, verbundenen Aufnahmegeräts (d. h. den Namen einer Webcam, Kamera, eines Bildschirms usw.) an die input-Methode übergeben, um Live-Medien von Ihrem verbundenen Gerät über das Netzwerk zu streamen.
video = ffmpeg_streaming.input('CAMERA NAME OR SCREEN NAME', capture=True)
Dynamic Adaptive Streaming over HTTP (DASH), auch bekannt als MPEG-DASH, ermöglicht hochwertiges Streaming über das Internet, indem Inhalte in kurze HTTP-basierte Datei-Downloads segmentiert werden. Clients können das Segment mit der höchsten Bitrate wählen, die für ihre Netzwerkbedingungen geeignet ist, was zu einem nahtlosen Wiedergabeerlebnis führt. Mehr erfahren
Die Bibliothek generiert automatisch Manifest (MPD)- und Segmentdateien.
from ffmpeg_streaming import Formats
dash = video.dash(Formats.h264())
dash.auto_generate_representations()
dash.output('/var/media/dash.mpd')
Um die genaue Kilobit-Rate und Größe für jeden Stream festzulegen, erstellen Sie manuell Representation-Objekte und fügen Sie sie der dash- oder hls-Instanz hinzu:
from ffmpeg_streaming import Formats, Bitrate, Representation, Size
_144p = Representation(Size(256, 144), Bitrate(95 * 1024, 64 * 1024))
_240p = Representation(Size(426, 240), Bitrate(150 * 1024, 94 * 1024))
_360p = Representation(Size(640, 360), Bitrate(276 * 1024, 128 * 1024))
_480p = Representation(Size(854, 480), Bitrate(750 * 1024, 192 * 1024))
_720p = Representation(Size(1280, 720), Bitrate(2048 * 1024, 320 * 1024))
_1080p = Representation(Size(1920, 1080), Bitrate(4096 * 1024, 320 * 1024))
_2k = Representation(Size(2560, 1440), Bitrate(6144 * 1024, 320 * 1024))
_4k = Representation(Size(3840, 2160), Bitrate(17408 * 1024, 320 * 1024))
dash = video.dash(Formats.h264())
dash.representations(_144p, _240p, _360p, _480p, _720p, _1080p, _2k, _4k)
dash.output('/var/media/dash.mpd')
Um automatisch HLS-Playlists für DASH und HLS zu generieren, verwenden Sie die auto_generate_representations
-Methode:
from ffmpeg_streaming import Formats
dash = video.dash(Formats.h264())
dash.auto_generate_representations([1080, 720, 480])
dash.generate_hls_playlist()
dash.output('/var/media/dash.mpd')
Für Live-Streaming von einer Kamera oder einem Bildschirm erstellen Sie Representation-Objekte und fügen Sie sie der dash-Instanz hinzu:
from ffmpeg_streaming import Formats, Bitrate, Representation, Size
_240p = Representation(Size(426, 240), Bitrate(150 * 1024, 94 * 1024))
_360p = Representation(Size(640, 360), Bitrate(276 * 1024, 128 * 1024))
dash = video.dash(Formats.h264())
dash.representations(_240p, _360p)
dash.output('/var/media/dash.mpd')
auto_generate_representations
-Methode kann
nicht für kamerabasierte Medien verwendet werden.
HTTP Live Streaming (auch bekannt als HLS) ist ein adaptives Bitraten-Streaming-Protokoll. Es verwendet HTTP-basierte Datei-Downloads und M3U-Playlists. Mehr erfahren
Um HLS-Dateien zu erstellen, verwenden Sie die hls
-Instanz und geben Sie den
Ausgabedateinamen an:
from ffmpeg_streaming import Formats
hls = video.hls(Formats.h264())
hls.auto_generate_representations()
hls.output('/var/media/hls.m3u8')
Um die genaue Kilobit-Rate und Größe für jeden Stream festzulegen, erstellen Sie manuell Representation-Objekte und fügen Sie sie der dash- oder hls-Instanz hinzu:
from ffmpeg_streaming import Formats, Bitrate, Representation, Size
_360p = Representation(Size(640, 360), Bitrate(276 * 1024, 128 * 1024))
_480p = Representation(Size(854, 480), Bitrate(750 * 1024, 192 * 1024))
_720p = Representation(Size(1280, 720), Bitrate(2048 * 1024, 320 * 1024))
hls = video.hls(Formats.h264())
hls.representations(_360p, _480p, _720p)
hls.output('/var/media/hls.m3u8')
Für das fragmentierte MP4-Format in HLS verwenden Sie die fragmented_mp4
-Methode:
from ffmpeg_streaming import Formats
hls = video.hls(Formats.h264())
hls.auto_generate_representations([360, 240])
hls.fragmented_mp4()
hls.output('/var/media/hls.m3u8')
Für Live-Streaming von einer Kamera oder einem Bildschirm verwenden Sie die hls
-Instanz
und geben Sie den Ausgabedateinamen an:
from ffmpeg_streaming import Formats, Bitrate, Representation, Size
_480p = Representation(Size(854, 480), Bitrate(750 * 1024, 192 * 1024))
hls = video.hls(Formats.h264(), hls_list_size=10, hls_time=5)
hls.flags('delete_segments')
hls.representations(_480p)
hls.output('/var/media/hls.m3u8')
auto_generate_representations
-Methode kann
nicht für kamerabasierte Medien verwendet werden. HEVC- und VP9-Formate werden für HLS-Packaging
nicht unterstützt, es sei denn, Sie verwenden fragmentiertes MP4.
HLS-Verschlüsselung verwendet den Advanced Encryption Standard (AES) im Cipher Block Chaining (CBC)-Modus. Das bedeutet, dass jeder Block mit dem Chiffriertext des vorherigen Blocks verschlüsselt wird. Mehr erfahren
Der folgende Code generiert einen einzigen Schlüssel für alle Segmente:
from ffmpeg_streaming import Formats
#A path you want to save a random key to your local machine
save_to = '/home/public_html/"PATH TO THE KEY DIRECTORY"/key'
#A URL (or a path) to access the key on your website
url = 'https://www.quasarstream.com/?"PATH TO THE KEY DIRECTORY"/key'
# or url = '/"PATH TO THE KEY DIRECTORY"/key';
hls = video.hls(Formats.h264())
hls.encryption(save_to, url)
hls.auto_generate_representations()
hls.output('/var/media/hls.m3u8')
Sie können die Verschlüsselungsschlüssel optional regelmäßig rotieren, indem Sie einen "Schlüsselrotationszeitraum" an die Verschlüsselungsmethode übergeben. Dadurch wird nach einer bestimmten Anzahl von Segmenten ein neuer Schlüssel generiert. Zum Beispiel wird bei einem Wert von 10 alle 10 Segmente ein neuer Schlüssel erstellt.
from ffmpeg_streaming import Formats
#A path you want to save a random key to your server
save_to = '/home/public_html/"PATH TO THE KEY DIRECTORY"/key'
#A URL (or a path) to access the key on your website
url = 'https://www.quasarstream.com/?"PATH TO THE KEY DIRECTORY"/key'
# or url = '/PATH TO THE KEY DIRECTORY/key';
hls = video.hls(Formats.h264())
hls.encryption(save_to, url, 10)
hls.auto_generate_representations([])
hls.output('/var/media/hls.m3u8')
Obwohl FFmpeg AES-Verschlüsselung für HLS unterstützt, ist es keine vollständige Digital Rights Management (DRM)-Lösung. Für eine vollständige DRM-Lösung sollten Sie FairPlay Streaming in Betracht ziehen, das einen sicheren Schlüsselaustausch und Wiedergabeschutz auf allen Geräten bietet. Weitere Optionen sind PlayReady von Microsoft und Widevine von Google.
Es ist entscheidend, Ihre Verschlüsselungsschlüssel auf Ihrer Website zu sichern. Hier sind einige Methoden:
Der folgende Code demonstriert, wie der Transkodierungsprozess überwacht wird:
from ffmpeg_streaming import Formats
import sys
def monitor(ffmpeg, duration, time_, time_left, process):
"""
This function allows you to handle the transcoding process according to your needs.
Examples:
1. Logging or printing ffmpeg log
logging.info(ffmpeg) or print(ffmpeg)
2. Handling Process object based on specific events
if "something happened":
process.terminate()
3. Sending email notifications about completion time
if time_left > 3600 and not already_send:
# Send email if process takes more than an hour
ready_time = time_left + time.time()
Email.send(
email='[email protected]',
subject='Your video will be ready by %s' % datetime.timedelta(seconds=ready_time),
message='Your video takes more than %s hour(s) ...' % round(time_left / 3600)
)
already_send = True
4. Creating a progress bar or displaying other parameters to users
Socket.broadcast(
address=127.0.0.1
port=5050
data={
percentage = per,
time_left = datetime.timedelta(seconds=int(time_left))
}
)
:param ffmpeg: ffmpeg command line
:param duration: video duration
:param time_: current time of transcoded video
:param time_left: seconds left to finish transcoding
:param process: subprocess object
"""
per = round(time_ / duration * 100)
sys.stdout.write(
"\rTranscoding...(%s%%) %s left [%s%s]" %
(per, datetime.timedelta(seconds=int(time_left)), '#' * per, '-' * (100 - per))
)
sys.stdout.flush()
hls = video.hls(Formats.h264())
hls.auto_generate_representations([1080, 720, 480])
hls.output('/var/media/hls.m3u8', monitor=monitor)
Sie können den Ausgabeort festlegen, indem Sie einen lokalen Pfad an die output
-Methode übergeben.
Wenn das Verzeichnis nicht existiert, erstellt die Bibliothek es automatisch für Sie.
Hier ist ein Beispiel mit DASH:
from ffmpeg_streaming import Formats
dash = video.dash(Formats.h264())
dash.auto_generate_representations()
dash.output('/var/media/dash.mpd')
Wenn Sie den Ausgabeparameter weglassen, speichert die Bibliothek die Dateien standardmäßig im selben Verzeichnis wie die Eingabedatei.
Hier ist ein Beispiel mit HLS:
from ffmpeg_streaming import Formats
hls = video.hls(Formats.h264())
hls.auto_generate_representations()
hls.output() # Saves to the input file's directory
output
bereitstellen,
um sie auf Ihrem lokalen Computer zu speichern.
Die Bibliothek ermöglicht es Ihnen, gepackte Dateien direkt in Cloud-Speicherdiensten zu speichern. Diese Funktionalität ist derzeit auf Video-on-Demand (VOD) beschränkt und unterstützt kein Live-Streaming.
Dazu müssen Sie ein CloudManager-Objekt erstellen und Ihre Cloud-Speicher-Anmeldeinformationen konfigurieren. Hier ist ein Beispiel mit Amazon S3:
from ffmpeg_streaming import S3, CloudManager
s3 = S3(aws_access_key_id='YOUR_KEY_ID', aws_secret_access_key='YOUR_KEY_SECRET', region_name='YOUR_REGION')
save_to_s3 = CloudManager().add(s3, bucket_name="bucket-name")
hls.output(clouds=save_to_s3)
Details zur Konfiguration und Beispiele mit anderen Cloud-Anbietern wie Google Cloud Storage, Microsoft Azure Storage finden Sie unter dem bereitgestellten Link.
Zusätzlich können Sie eine lokale Kopie der Dateien speichern, während Sie in den Cloud-Speicher hochladen:
hls.output('/var/media/hls.m3u8', clouds=save_to_s3)
Eine Illustration des End-to-End-Prozesses.
Cloud
Lokal
Cloud
Lokal
Diese Methode ermöglicht es Ihnen, die segmentierten Dateien hochzuladen und Manifestdateien direkt auf einem HTTP-Server oder anderen unterstützten Protokollen wie FTP zu aktualisieren. Diese Funktionalität eignet sich für Live-Streaming-Szenarien.
# DASH
dash.output('http://YOUR-WEBSITE.COM/live-stream/out.mpd')
# HLS
hls.save_master_playlist('/var/media/hls.m3u8')
#Before running the following code, ensure you've uploaded the master playlist file (/var/media/hls.m3u8) to your server using FTP or another method.
hls.output('ftp://[user[:password]@]server[:port]/var/media/hls.m3u8')
Dieser Abschnitt erklärt, wie Sie mit unserer Bibliothek Informationen aus einer Videodatei extrahieren können.
from ffmpeg_streaming import FFProbe
# Specify the video file path
video_path = '/var/media/video.mp4'
# Create an FFProbe object
ffprobe = FFProbe(video_path)
# Save extracted information as JSON
ffprobe.save_as_json('probe.json')
# Access various data points
# All media information
all_media = ffprobe.all()
# Video format details
video_format = ffprobe.format()
# Stream information (all, video, audio)
streams = ffprobe.streams().all()
videos = ffprobe.streams().videos()
audios = ffprobe.streams().audios()
# Access individual streams
first_stream = ffprobe.streams().first_stream()
first_video = ffprobe.streams().video()
first_audio = ffprobe.streams().audio()
# Print extracted information
print("All Media Information:")
print(all_media)
print("\nVideo Format:")
print(video_format)
print("\nStreams:")
print(streams)
print("\nVideo Streams:")
for video in videos:
print(video)
print("\nAudio Streams:")
for audio in audios:
print(audio)
print("\nFirst Stream:")
print(first_stream)
print("\nFirst Video Stream:")
print(first_video)
print("\nFirst Audio Stream:")
print(first_audio)
# Calculate and print additional details
duration_seconds = float(video_format.get('duration', 0))
duration = datetime.timedelta(seconds=duration_seconds)
print(f"\nDuration: {duration}") # f-string for formatted output
size_kb = int(video_format.get('size', 0)) / 1024
print(f"Size: {round(size_kb)} KB") # f-string with round function
bitrate_kb = int(video_format.get('bit_rate', 0)) / 1024
print(f"Overall Bitrate: {round(bitrate_kb)} KB") # f-string
dimensions = (
first_video.get('width', "Unknown"),
first_video.get('height', "Unknown")
)
print(f"Dimensions: {dimensions[0]}x{dimensions[1]}") # f-string
video_bitrate_kb = int(first_video.get('bit_rate', 0)) / 1024
print(f"Video Bitrate: {round(video_bitrate_kb)} KB") # f-string
audio_bitrate_kb = int(first_audio.get('bit_rate', 0)) / 1024
print(f"Audio Bitrate: {round(audio_bitrate_kb)} KB") # f-string
Dieser Abschnitt demonstriert, wie Sie Streams mit unserer Bibliothek konvertieren. Sie geben eine Manifest-URL an die input-Methode weiter.
from ffmpeg_streaming import Formats, Bitrate, Representation, Size
# Replace with the actual HLS manifest URL
hls_url = 'https://www.quasarstream.com/?PATH/TO/HLS-MANIFEST.M3U8'
# Define a video representation
_480p = Representation(Size(854, 480), Bitrate(750 * 1024, 192 * 1024))
# Create a DASH output
video = ffmpeg_streaming.input(hls_url)
dash = video.dash(Formats.h264())
dash.representations(_480p)
dash.output('/var/media/dash.mpd')
from ffmpeg_streaming import Formats
# Replace with the actual DASH manifest URL
dash_url = 'https://www.quasarstream.com/?PATH/TO/DASH-MANIFEST.MPD'
# Create an HLS output
video = ffmpeg_streaming.input(dash_url)
hls = video.hls(Formats.h264())
hls.auto_generate_representations()
hls.output('/var/media/hls.m3u8')
from ffmpeg_streaming import Formats
# Replace with the actual manifest URL (DASH or HLS)
manifest_url = 'https://www.quasarstream.com/?PATH/TO/MANIFEST.MPD or M3U8'
# Create a file output
video = ffmpeg_streaming.input(manifest_url)
stream = video.stream2file(Formats.h264())
stream.output('/var/media/new-video.mp4')
Empfohlene Open-Source-Player zum Abspielen von gepackten Videos:
Plattform | Player | Unterstützte Formate |
---|---|---|
Android | AndroidX Media | DASH & HLS |
iOS | Native Player | HLS |
Windows/Linux/macOS | FFmpeg (ffplay), VLC media player | DASH & HLS |
Wenn Sie dieses Projekt nützlich finden, unterstützen Sie uns bitte: