Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
S
SHMCamStudio
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
SexHackMe
SHMCamStudio
Commits
a5d8432d
Commit
a5d8432d
authored
Jun 18, 2025
by
Stefy Lanza (nextime / spora )
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added initial browser control
parent
815adc2c
Changes
4
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
865 additions
and
0 deletions
+865
-0
shmcamstudio
shmcamstudio
+12
-0
browser.py
shmcs/browser.py
+93
-0
webpanel.py
shmcs/webpanel.py
+3
-0
chat.html
templates/chat.html
+757
-0
No files found.
shmcamstudio
View file @
a5d8432d
...
...
@@ -69,6 +69,7 @@ from shmcs.webpanel import run_flask_app
from
shmcs.panel
import
create_panel_gui
from
shmcs.studio
import
run_camstudio
from
shmcs.obs
import
run_obs_controller
from
shmcs.browser
import
run_browser
def
main
():
# Setup argument parser
...
...
@@ -80,6 +81,8 @@ def main():
parser
.
add_argument
(
'--port'
,
type
=
int
,
default
=
5000
,
help
=
'Port for the web interface (default: 5000)'
)
parser
.
add_argument
(
'--browser'
,
action
=
"store_true"
,
help
=
'launch local web browser'
)
# Parse arguments
args
=
parser
.
parse_args
()
...
...
@@ -100,6 +103,15 @@ def main():
)
obs_thread
.
start
()
if
args
.
browser
:
browser_thread
=
threading
.
Thread
(
target
=
run_browser
,
kwargs
=
{},
daemon
=
True
)
logger
.
info
(
"Browser launch requested"
)
browser_thread
.
start
()
# Daemon mode for web interface
if
args
.
nogui
or
args
.
daemon
:
run_camstudio
(
args
.
daemon
)
...
...
shmcs/browser.py
0 → 100644
View file @
a5d8432d
import
platform
import
asyncio
from
playwright.async_api
import
async_playwright
import
argparse
import
os
from
datetime
import
datetime
from
pathlib
import
Path
import
logging
logging
.
getLogger
(
__name__
)
async
def
monitor_stream
(
log_path
,
domain
):
async
with
async_playwright
()
as
p
:
try
:
browser
=
await
p
.
chromium
.
connect_over_cdp
(
"http://localhost:9222"
)
except
:
user_data_dir
=
'./user-data'
cont
=
await
p
.
chromium
.
launch_persistent_context
(
user_data_dir
,
headless
=
False
,
args
=
[
"--disable-infobars"
,
"--disable-features=Antaniu"
],
ignore_default_args
=
[
"--enable-automation"
,
"--no-sandbox"
],)
pages
=
cont
.
pages
if
pages
:
page
=
pages
[
0
]
else
:
page
=
await
cont
.
new_page
()
logger
.
info
(
page
.
url
)
await
page
.
goto
(
'http://localhost:5000/chat'
)
logger
.
info
(
"Browser session retained"
)
#await browser.close()
browser
=
cont
.
browser
while
True
:
browser
=
cont
.
browser
if
browser
:
contexts
=
browser
.
contexts
else
:
contexts
=
[
cont
]
for
context
in
contexts
:
for
page
in
context
.
pages
:
if
domain
in
page
.
url
:
print
(
f
"Found Streamate tab"
)
await
monitor_requests
(
page
,
log_path
)
await
asyncio
.
sleep
(
5
)
# Check every 5 seconds
async
def
monitor_requests
(
page
,
log_path
):
async
def
log_request
(
request
):
if
request
.
resource_type
not
in
[
'document'
,
'image'
,
'font'
,
'stylesheet'
]:
log_entry
=
f
"[{datetime.now()}] Request: {request.method} {request.url}
\n
"
with
open
(
log_path
,
'a'
)
as
f
:
f
.
write
(
log_entry
)
async
def
log_response
(
response
):
#print(await response.body())
#print(response.request.resource_type)
#if response.request.resource_type not in ['document', 'image', 'font', 'stylesheet']:
if
response
.
request
.
resource_type
in
[
'xhr'
]
and
not
response
.
url
.
endswith
(
".mp3"
):
log_entry
=
f
"[{datetime.now()}] Response: {response.status} {response.url} -> BODY: "
log_body
=
await
response
.
body
()
with
open
(
log_path
,
'a'
)
as
f
:
f
.
write
(
log_entry
)
print
(
log_body
)
f
.
write
(
str
(
log_body
))
f
.
write
(
"
\n\n
"
)
async
def
log_websocket
(
ws
):
def
writelog
(
payload
,
origin
,
url
):
logging
.
info
(
origin
+
": "
+
str
(
payload
)
+
"
\n
"
)
log_entry
=
f
"[{datetime.now()}] WS: {origin} {url} -> Message: "
with
open
(
log_path
,
'a'
)
as
f
:
f
.
write
(
log_entry
)
f
.
write
(
origin
+
": "
)
f
.
write
(
str
(
payload
)
+
"
\n\n
"
)
logging
.
info
(
f
"WebSocket opened: {ws.url}"
)
ws
.
on
(
"framesent"
,
lambda
payload
:
writelog
(
payload
,
'framesent'
,
ws
.
url
))
ws
.
on
(
"framereceived"
,
lambda
payload
:
writelog
(
payload
,
'framereceived'
,
ws
.
url
))
ws
.
on
(
"close"
,
lambda
payload
:
print
(
"WebSocket closed"
))
page
.
on
(
"request"
,
log_request
)
page
.
on
(
"response"
,
log_response
)
page
.
on
(
"websocket"
,
log_websocket
)
while
True
:
await
asyncio
.
sleep
(
1
)
def
run_browser
():
lpath
=
str
(
Path
(
Path
.
home
(),
Path
(
'streamon.log'
)))
#parser = argparse.ArgumentParser(description="Monitor Streamate requests")
#parser.add_argument("--log_path", type=str, default=lpath,
# help="Path to the log file")
#parser.add_argument("--domain", type=str, default="performerclient.streamatemodels.com",
# help="URL to monitor")
#args = parser.parse_args()
logging
.
info
(
"Starting browser..."
)
log_dir
=
os
.
path
.
dirname
(
lpath
)
if
log_dir
and
not
os
.
path
.
exists
(
log_dir
):
os
.
makedirs
(
log_dir
)
asyncio
.
run
(
monitor_stream
(
lpath
,
"performerclient.streamatemodels.com"
))
shmcs/webpanel.py
View file @
a5d8432d
...
...
@@ -147,6 +147,9 @@ def stream():
return
render_template
(
'stream.html'
,
stream_url
=
stream_url
)
@
flask_app
.
route
(
"/chat"
)
def
chat
():
return
render_template
(
'chat.html'
)
@
socketio
.
event
def
my_event
(
message
):
...
...
templates/chat.html
0 → 100644
View file @
a5d8432d
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment