[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