[FFmpeg-user] Creating a Simulated HLS Streaming Server with FFmpeg...HOW??
Norm Kaiser
norm_kaiser at hotmail.com
Sat Jul 29 21:08:51 EEST 2023
Good point, gentlemen. Here is ffmpeg command I'm using:
hls_command = (
f'ffmpeg -re {start_time_option} -i "{input_file}" '
'-c:v libx264 -c:a aac '
f'-f hls -hls_time {segment_duration} -hls_list_size {playlist_size} '
'-hls_flags delete_segments -hls_segment_type fmp4 -hls_flags omit_endlist -segment_list_flags +live '
'-hls_flags delete_segments+omit_endlist+append_list -hls_segment_type fmp4 '
f'-hls_delete_threshold {delete_threshold} -hls_playlist_type event '
f'-hls_segment_filename "{segment_filename}" "{output_playlist}"'
)
And here is the current state of the Python. Bear with me, as I've done a lot of try this, try that to the code:
import datetime
import subprocess
import psutil
import os
import shlex
import random
import string
from pynput import keyboard
import time
#*************** START VARIABLE DECLARATION SECTION *************
ThePlaylistThatIsPlaying = ""
TheVideoThatIsPlaying = ""
TheTimeToStart = 0
FFMpegProc = None
#**************** END VARIABLE DECLARATION SECTION **************
def show_message_box():
# Create a basic tkinter window (you can hide it if you want)
root = tk.Tk()
root.withdraw()
#*************************************************************************
#************************** START FUNCTION SECTION ***********************
#*************************************************************************
def generate_random_letters():
letters = string.ascii_letters
return ''.join(random.choice(letters) for _ in range(8))
#This function reads the playlist from a text file into memory.
def ReadInThePlaylist(PlaylistToBeReadIn):
PlaylistToBeReadIn = "/home/norm/" + PlaylistToBeReadIn
lines = []
with open(PlaylistToBeReadIn, 'r', encoding='utf-8-sig') as file:
for line in file:
line = line.strip() # Remove leading/trailing whitespace and newline characters
words = line.split() # Split the line into a list of words
lines.append(words) # Append the list of words to the lines list
return lines
#The function below is what actually plays the stream.
def StartVideoStream(input_file, output_directory, output_playlist, start_time=0, segment_duration=2, playlist_size=6, delete_threshold=24):
os.makedirs(output_directory, exist_ok=True)
segmentRandomName = "segment" + "%03d.ts"
segment_filename = os.path.join(output_directory, segmentRandomName)
output_playlist = os.path.join(output_directory, output_playlist)
start_time_option = f"-ss {start_time}" if start_time > 0 else ""
#-f concat
hls_command = (
f'ffmpeg -re {start_time_option} -i "{input_file}" '
'-c:v libx264 -c:a aac -preset ultrafast '
f'-f hls -hls_time {segment_duration} -hls_list_size {playlist_size} '
'-hls_flags delete_segments -hls_segment_type fmp4 -hls_flags omit_endlist -segment_list_flags +live '
'-hls_flags delete_segments+omit_endlist+append_list -hls_segment_type fmp4 '
f'-hls_delete_threshold {delete_threshold} -hls_playlist_type event '
f'-hls_segment_filename "{segment_filename}" "{output_playlist}"'
)
try:
# Run the ffmpeg command to start HLS streaming
proc = subprocess.run(hls_command, shell=True)
print("HLS streaming started successfully.")
except subprocess.CalledProcessError as e:
print(f"Error while running ffmpeg: {e}")
return proc
#*************************************************************************
#************************** END FUNCTION SECTION *************************
#*************************************************************************
#Let's create a custom class to hold the playlist entries.
class VideoAsset:
def __init__(self, InPoint, OutPoint, Path, AssetType, Bug, Weekday, StartTimeAsText):
self.InPoint = InPoint
self.OutPoint = OutPoint
self.Path = Path
self.AssetType = AssetType
self.Bug = Bug
self.Weekday = Weekday
self.StartTimeAsText = StartTimeAsText
#**************** DETERMINE WHAT MOVIE SHOULD BE PLAYING **********
# In this section we have to first determine which playlist is today's.
# Then we read it in to memory by calling the ReadInThePlaylist function.
d = datetime.datetime.now()
Today = datetime.date.today()
Year = Today.strftime("%Y")
Month = d.strftime("%m")
Day = d.strftime("%d")
CurrentHour = d.hour
CurrentMinutes = d.minute
CurrentSeconds = d.second
ThePlaylistThatShouldBePlaying = Year + "-" + Month + "-" + Day + ".txt"
if ThePlaylistThatIsPlaying != ThePlaylistThatShouldBePlaying:
ThePlaylistThatIsPlaying = ThePlaylistThatShouldBePlaying
PlaylistFile = ReadInThePlaylist(ThePlaylistThatIsPlaying)
Playlist = []
for i in range(0, len(PlaylistFile) - 1):
#OK, playlist file is in memory...now we load it into an array of our custom VIDEOASSET object so it resembles a database.
Playlist.append(VideoAsset(int(PlaylistFile[i][0]), int(PlaylistFile[i][1]), PlaylistFile[i][2], PlaylistFile[i][3], "", "", ""))
#OK, so now we have the playlist in memory in a custom object. Now we have to do the time calculation to figure out what time of day it is
#and play the right movie at the right start time.
TimeOfDayInSeconds = (CurrentHour * 3600) + (CurrentMinutes * 60) + CurrentSeconds
Found = False
TheCounter = 0
while not Found:
if TimeOfDayInSeconds >= Playlist[TheCounter].InPoint and TimeOfDayInSeconds < Playlist[TheCounter].OutPoint:
TheVideoThatShouldBePlaying = Playlist[TheCounter].Path
TheTimeToStart = (TimeOfDayInSeconds - Playlist[TheCounter].InPoint)
Found = True
#In here write the asset type checking, if you want to
TheCounter = TheCounter + 1
print(TheTimeToStart)
if TheVideoThatShouldBePlaying != TheVideoThatIsPlaying:
TheVideoThatIsPlaying = TheVideoThatShouldBePlaying
#StartVideoStream("/home/norm/test.mrp4", "/var/www/nginx-default", "playlist.m3u8", 120)
def press_callback(key):
global FFMpegProc
print('{}'.format(key))
if '{}'.format(key) == "'r'":
FFMpegProc = StartVideoStream("/home/norm/Logo2.mp4", "/var/www/nginx-default", "playlist.m3u8", 0)
FFMpegProc = StartVideoStream("/home/norm/Logo2.mp4", "/var/www/nginx-default", "playlist.m3u8", 0)
FFMpegProc = StartVideoStream("/home/norm/Logo2.mp4", "/var/www/nginx-default", "playlist.m3u8", 0)
FFMpegProc = StartVideoStream("/home/norm/Logo2.mp4", "/var/www/nginx-default", "playlist.m3u8", 0)
FFMpegProc = StartVideoStream("/home/norm/Logo2.mp4", "/var/www/nginx-default", "playlist.m3u8", 0)
FFMpegProc = StartVideoStream("/home/norm/Logo2.mp4", "/var/www/nginx-default", "playlist.m3u8", 0)
FFMpegProc = StartVideoStream("/home/norm/Logo2.mp4", "/var/www/nginx-default", "playlist.m3u8", 0)
FFMpegProc = StartVideoStream("/home/norm/test.mp4", "/var/www/nginx-default", "playlist.m3u8", 0)
FFMpegProc = StartVideoStream("/home/norm/Logo2.mp4", "/var/www/nginx-default", "playlist.m3u8", 0)
print('I should start')
if '{}'.format(key) == "'o'":
FFMpegProc = StartVideoStream("/home/norm/Logo2.mp4", "/var/www/nginx-default", "playlist.m3u8", 0)
l = keyboard.Listener(on_press=press_callback)
l.start()
l.join()
Thank you so much!
Norm
________________________________
From: ffmpeg-user <ffmpeg-user-bounces at ffmpeg.org> on behalf of Vincent Deconinck <vdeconinck at gmail.com>
Sent: Saturday, July 29, 2023 12:28 PM
To: FFmpeg user questions <ffmpeg-user at ffmpeg.org>
Subject: Re: [FFmpeg-user] Creating a Simulated HLS Streaming Server with FFmpeg...HOW??
> People will probably ask you to post your code as a gist.
>
Indeed, or at least just post here the ffmpeg commands you are currently
using.
KR,
Vincent
_______________________________________________
ffmpeg-user mailing list
ffmpeg-user at ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-user
To unsubscribe, visit link above, or email
ffmpeg-user-request at ffmpeg.org with subject "unsubscribe".
More information about the ffmpeg-user
mailing list