Commit b9d880fa authored by nextime's avatar nextime

Split program in modules and share config by using builtins

parent 30905fdb
This diff is collapsed.
...@@ -25,3 +25,10 @@ window_title = SHM Cam Studio ...@@ -25,3 +25,10 @@ window_title = SHM Cam Studio
button_width = 20 button_width = 20
button_height = 2 button_height = 2
font_size = 12 font_size = 12
[OBS:mdma]
host = 192.168.42.115
port = 4455
password = motorol4
import sys, os
sys.path+=[os.path.dirname(__file__)]
from utils import *
# Copyright (C) 2023 Stefy Lanza <stefy@nexlab.net> and SexHack.me
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import tkinter as tk
from tkinter import font as tkFont
import vlc
import webbrowser
import sys
import os
from utils import run_command
class VideoPlayer:
def __init__(self, master, video_url):
self.master = master
# VLC player setup
args = []
_isLinux = sys.platform.startswith('linux')
if _isLinux:
args.append('--vout=mmal_vout')
# Create a VLC instance
self.Instance = vlc.Instance(args)
# Create a new MediaPlayer
self.player = self.Instance.media_player_new()
# Set the media
media = self.Instance.media_new(video_url)
self.player.set_media(media)
# Create a frame for the video
self.video_frame = self.master
self.video_frame.pack(fill=tk.BOTH, expand=True)
self.canvas = tk.Canvas(self.video_frame, width=800)
self.canvas.pack(fill=tk.BOTH, expand=True)
# Embed the VLC Video
win_id = self.canvas.winfo_id()
if _isLinux:
self.player.set_xwindow(win_id)
else:
self.player.set_hwnd(win_id)
# Play the video
self.player.play()
def create_panel_gui():
# Create the main window
window = tk.Tk()
window.title(config.get("Tkinter", "window_title", fallback="SHM CamStudio"))
helv36 = tkFont.Font(family='Helvetica', size=config.get("Tkinter", "font_size", fallback=12), weight='bold')
# Frame for the left side
fleft = tk.Frame(window)
fleft.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
# URL of your RTMP stream
video_url = config.get("General", "rtmp_url", fallback="rtmp://192.168.42.1/record/Live")
VideoPlayer(fleft, video_url)
# Frame for the right side
fright = tk.Frame(window)
fright.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
# Frame for the first two rows in the right frame
frame1 = tk.Frame(fright)
frame1.pack(fill=tk.BOTH, expand=True)
# Buttons configuration
buttons_row0 = [
('PRIVATE STEFY', 'smblur_private_stefy'),
('PRIVATE LEELOO', 'smblur_private_leeloo'),
('PRIVATE JASMIN', 'smblur_private_jasmin'),
('PRIVATE OTHER', 'smblur_private')
]
buttons_row1 = [
('OPEN/CLOSE STEFY', 'smblur_stefy'),
('OPEN/CLOSE LEELOO', 'smblur_leeloo'),
('OPEN/CLOSE JASMIN', 'smblur_jasmin'),
('OPEN/CLOSE OTHERS', 'smblur_shine')
]
# Create buttons for the first two rows
for j, (text, command) in enumerate(buttons_row0):
button = tk.Button(frame1, text=text, font=helv36, width=25, height=15, bg="green", fg="white",
command=lambda cmd=command: run_command(cmd))
button.grid(row=0, column=j, sticky='nsew')
for j, (text, command) in enumerate(buttons_row1):
button = tk.Button(frame1, text=text, font=helv36, width=25, height=15, bg="green", fg="white",
command=lambda cmd=command: run_command(cmd))
button.grid(row=1, column=j, sticky='nsew')
# Configure the columns in the first frame
for i in range(4):
frame1.grid_columnconfigure(i, weight=1)
# Frame for the third row in the right frame
frame2 = tk.Frame(fright)
frame2.pack(fill=tk.BOTH, expand=True)
# Row 2 with 3 buttons
buttons_row2 = [
('TEASE', 'smblur_tease'),
('TEASE ALL', 'smblur_teaseall'),
('OPEN', 'smblur_clean')
]
# Create buttons for the third row
for j, (text, command) in enumerate(buttons_row2):
button = tk.Button(frame2, text=text, font=helv36, width=30, height=25, bg="blue", fg="white",
command=lambda cmd=command: run_command(cmd))
button.grid(row=0, column=j, sticky='nsew')
# Configure the columns in the second frame
for i in range(3):
frame2.grid_columnconfigure(i, weight=1)
# Add a button to open web interface
web_button = tk.Button(frame2, text="Open Web Interface",
command=lambda: webbrowser.open('http://localhost:5000'),
bg="purple", fg="white", font=helv36)
web_button.grid(row=1, column=1, sticky='nsew')
return window
# Copyright (C) 2023 Stefy Lanza <stefy@nexlab.net> and SexHack.me
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import subprocess
import socket
import os
import sys
def run_command(command):
try:
result = subprocess.run(command, shell=True, check=True,
capture_output=True, text=True)
logger.info(f"Command executed: {command}")
return result.stdout
except subprocess.CalledProcessError as e:
logger.error(f"Error executing command {command}: {e}")
return f"Error: {e}"
def check_port_available(port):
"""Check if a port is available"""
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
return s.connect_ex(('localhost', port)) != 0
def create_daemon():
if os.name == 'posix': # Unix-like systems
try:
# First fork
pid = os.fork()
if pid > 0:
# Exit first parent
sys.exit(0)
except OSError as err:
logger.error(f'Fork #1 failed: {err}')
sys.exit(1)
# Decouple from parent environment
os.chdir('/')
os.setsid()
os.umask(0)
# Second fork
try:
pid = os.fork()
if pid > 0:
# Exit from second parent
sys.exit(0)
except OSError as err:
logger.error(f'Fork #2 failed: {err}')
sys.exit(1)
# Redirect standard file descriptors
sys.stdout.flush()
sys.stderr.flush()
si = open(os.devnull, 'r')
so = open(os.devnull, 'a+')
se = open(os.devnull, 'a+')
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
elif os.name == 'nt': # Windows
try:
# Hide the console window
si = subprocess.STARTUPINFO()
si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
# Start the script as a new process
subprocess.Popen([sys.executable, __file__],
startupinfo=si,
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
# Exit the current process
sys.exit(0)
except Exception as err:
logger.error(f'Failed to create background process: {err}')
sys.exit(1)
else:
logger.error(f'Unsupported operating system: {os.name}')
sys.exit(1)
# Copyright (C) 2023 Stefy Lanza <stefy@nexlab.net> and SexHack.me
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from flask import Flask, render_template, request
from utils import check_port_available, run_command, create_daemon
import sys
import os
# Flask App Setup
flask_app = Flask('SHMCamStudio', template_folder=TEMPLATE_DIR)
@flask_app.route('/')
def index():
return render_template('index.html', commands=COMMANDS)
@flask_app.route('/execute', methods=['POST'])
def execute():
command_key = request.form.get('command')
if command_key in COMMANDS:
result = run_command(COMMANDS[command_key])
return result
else:
return "Invalid command", 400
@flask_app.route('/stream')
def stream():
stream_url = config.get('Web', 'stream_url', fallback="https://192.168.42.1/HLS/record/Live.m3u8")
return render_template('stream.html', stream_url=stream_url)
def run_flask_app(port=5000, daemon_mode=False):
"""Run Flask app with optional daemon mode"""
if not check_port_available(port):
logger.error(f"Port {port} is already in use")
sys.exit(1)
logger.info(f"Starting Flask app on port {port}")
if daemon_mode and sys.platform != 'win32':
create_daemon()
flask_app.run(host='0.0.0.0', port=port, debug=False, use_reloader=False)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment