Added working tcp stream. Only issue is that it stops after a couple of minutes
This commit is contained in:
+8
-2
@@ -15,12 +15,13 @@ load_config() {
|
||||
[ -f "$CONFIG_FILE" ] || return
|
||||
SOURCE_TYPE=$(grep -o '"source_type":"[^"]*"' "$CONFIG_FILE" 2>/dev/null | cut -d'"' -f4)
|
||||
RTSP_URL=$(grep -o '"rtsp_url":"[^"]*"' "$CONFIG_FILE" 2>/dev/null | cut -d'"' -f4)
|
||||
TCP_URL=$(grep -o '"tcp_url":"[^"]*"' "$CONFIG_FILE" 2>/dev/null | cut -d'"' -f4)
|
||||
MP4_PATH=$(grep -o '"mp4_path":"[^"]*"' "$CONFIG_FILE" 2>/dev/null | cut -d'"' -f4)
|
||||
RES_W=$(grep -o '"res_w":[0-9]*' "$CONFIG_FILE" 2>/dev/null | cut -d: -f2)
|
||||
RES_H=$(grep -o '"res_h":[0-9]*' "$CONFIG_FILE" 2>/dev/null | cut -d: -f2)
|
||||
FPS=$(grep -o '"fps":[0-9]*' "$CONFIG_FILE" 2>/dev/null | cut -d: -f2)
|
||||
ROTATION=$(grep -o '"rotation":[0-9]*' "$CONFIG_FILE" 2>/dev/null | cut -d: -f2)
|
||||
: ${SOURCE_TYPE:=mp4} ${RTSP_URL:=rtsp://192.168.1.100:8554/stream}
|
||||
: ${SOURCE_TYPE:=mp4} ${RTSP_URL:=rtsp://192.168.1.100:8554/stream} ${TCP_URL:=tcp://192.168.1.100:5000}
|
||||
: ${MP4_PATH:=/sdcard/Movies/2.mp4} ${RES_W:=1920} ${RES_H:=1080} ${FPS:=30} ${ROTATION:=0}
|
||||
}
|
||||
|
||||
@@ -128,6 +129,11 @@ case "${1:-help}" in
|
||||
nohup "$FF" -rtsp_transport tcp -i "$RTSP_URL" \
|
||||
-vf "${VFILTER}scale=${RES_W}:${RES_H},fps=${FPS:-30}" \
|
||||
-f v4l2 -pix_fmt yuv420p /dev/video0 > /dev/null 2>&1 &
|
||||
elif [ "$SOURCE_TYPE" = "tcp" ]; then
|
||||
nohup "$FF" -fflags nobuffer -flags low_delay -analyzeduration 0 -use_wallclock_as_timestamps 1 \
|
||||
-i "$TCP_URL" \
|
||||
-vf "${VFILTER}scale=${RES_W}:${RES_H},fps=${FPS:-30}" \
|
||||
-f v4l2 -pix_fmt yuv420p /dev/video0 > /dev/null 2>&1 &
|
||||
elif [ "$SOURCE_TYPE" = "mp4" ] && [ -f "$MP4_PATH" ]; then
|
||||
nohup "$FF" -stream_loop -1 -re -i "$MP4_PATH" \
|
||||
-vf "${VFILTER}scale=${RES_W}:${RES_H},fps=${FPS:-30}" \
|
||||
@@ -150,7 +156,7 @@ case "${1:-help}" in
|
||||
;;
|
||||
get_config)
|
||||
load_config
|
||||
echo "{\"source_type\":\"$SOURCE_TYPE\",\"rtsp_url\":\"$RTSP_URL\",\"mp4_path\":\"$MP4_PATH\",\"res_w\":${RES_W:-1920},\"res_h\":${RES_H:-1080},\"fps\":${FPS:-30},\"rotation\":${ROTATION:-0}}"
|
||||
echo "{\"source_type\":\"$SOURCE_TYPE\",\"rtsp_url\":\"$RTSP_URL\",\"tcp_url\":\"$TCP_URL\",\"mp4_path\":\"$MP4_PATH\",\"res_w\":${RES_W:-1920},\"res_h\":${RES_H:-1080},\"fps\":${FPS:-30},\"rotation\":${ROTATION:-0}}"
|
||||
;;
|
||||
validate)
|
||||
PROVIDER_PID=$(pgrep -f "/virtual_camera_provider" | head -1)
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
<div class="card"><div class="card-title">Status</div><div id="status-msg" style="font-size:11px;color:#f85149;margin-bottom:6px"></div><div class="dashboard" id="status-dash"></div></div>
|
||||
<div class="card"><div class="card-title">Video Source</div><div class="source-selector">
|
||||
<button class="src-btn active" data-src="rtsp">RTSP</button>
|
||||
<button class="src-btn" data-src="tcp">TCP</button>
|
||||
<button class="src-btn" data-src="mp4">MP4</button>
|
||||
</div>
|
||||
<div id="rtsp-config"><label>RTSP URL</label><input type="text" id="rtsp-url" placeholder="rtsp://192.168.1.100:8554/stream"></div>
|
||||
<div id="tcp-config" class="hidden"><label>TCP URL</label><input type="text" id="tcp-url" placeholder="tcp://192.168.1.100:5000"></div>
|
||||
<div id="mp4-config" class="hidden"><label>MP4 Path</label><input type="text" id="mp4-path" placeholder="/sdcard/Download/video.mp4"></div>
|
||||
<div class="row"><div><label>Width</label><input type="number" id="res-w" value="1920" class="num"></div><div><label>Height</label><input type="number" id="res-h" value="1080" class="num"></div><div><label>FPS</label><input type="number" id="fps" value="30" class="num"></div></div>
|
||||
<div class="row"><div><label>Rotation</label><select id="rotation" class="num"><option value="0">0</option><option value="90">90</option><option value="180">180</option><option value="270">270</option></select></div></div>
|
||||
|
||||
+27
-1
@@ -28,15 +28,41 @@ document.getElementById('btn-unfeed')?.addEventListener('click',()=>run('stop_fe
|
||||
document.getElementById('btn-refresh')?.addEventListener('click',updateDash);
|
||||
document.getElementById('btn-save')?.addEventListener('click',()=>{
|
||||
const src=document.querySelector('.src-btn.active')?.dataset.src||'mp4';
|
||||
const json=JSON.stringify({source_type:src,rtsp_url:document.getElementById('rtsp-url').value,mp4_path:document.getElementById('mp4-path').value,res_w:parseInt(document.getElementById('res-w').value)||1920,res_h:parseInt(document.getElementById('res-h').value)||1080,fps:parseInt(document.getElementById('fps').value)||30,rotation:parseInt(document.getElementById('rotation').value)||0});
|
||||
const json=JSON.stringify({source_type:src,rtsp_url:document.getElementById('rtsp-url').value,tcp_url:document.getElementById('tcp-url').value,mp4_path:document.getElementById('mp4-path').value,res_w:parseInt(document.getElementById('res-w').value)||1920,res_h:parseInt(document.getElementById('res-h').value)||1080,fps:parseInt(document.getElementById('fps').value)||30,rotation:parseInt(document.getElementById('rotation').value)||0});
|
||||
ksu.exec("echo '"+json+"' > /data/local/tmp/virtualcam_config.json");
|
||||
log('Config saved','ok');
|
||||
// Restart feeder with new config if running
|
||||
try {
|
||||
const st = JSON.parse(ksu.exec(CMD+' status')||'{}');
|
||||
if (st.feeder_pid > 0) {
|
||||
ksu.exec(CMD+' stop_feeder');
|
||||
setTimeout(function(){ksu.exec(CMD+' start_feeder');log('Feeder restarted','ok');},2000);
|
||||
}
|
||||
} catch(e) {}
|
||||
});
|
||||
document.querySelectorAll('.src-btn').forEach(b=>b.addEventListener('click',()=>{
|
||||
document.querySelectorAll('.src-btn').forEach(x=>x.classList.remove('active'));
|
||||
b.classList.add('active');
|
||||
document.getElementById('rtsp-config').classList.toggle('hidden',b.dataset.src!=='rtsp');
|
||||
document.getElementById('tcp-config').classList.toggle('hidden',b.dataset.src!=='tcp');
|
||||
document.getElementById('mp4-config').classList.toggle('hidden',b.dataset.src!=='mp4');
|
||||
}));
|
||||
// Load saved config into UI fields
|
||||
try {
|
||||
const cfg = JSON.parse(ksu.exec(CMD+' get_config')||'{}');
|
||||
if (cfg.source_type) {
|
||||
document.querySelectorAll('.src-btn').forEach(b => b.classList.toggle('active', b.dataset.src === cfg.source_type));
|
||||
document.getElementById('rtsp-config').classList.toggle('hidden', cfg.source_type !== 'rtsp');
|
||||
document.getElementById('tcp-config').classList.toggle('hidden', cfg.source_type !== 'tcp');
|
||||
document.getElementById('mp4-config').classList.toggle('hidden', cfg.source_type !== 'mp4');
|
||||
}
|
||||
if (cfg.rtsp_url) document.getElementById('rtsp-url').value = cfg.rtsp_url;
|
||||
if (cfg.tcp_url) document.getElementById('tcp-url').value = cfg.tcp_url;
|
||||
if (cfg.mp4_path) document.getElementById('mp4-path').value = cfg.mp4_path;
|
||||
if (cfg.res_w) document.getElementById('res-w').value = cfg.res_w;
|
||||
if (cfg.res_h) document.getElementById('res-h').value = cfg.res_h;
|
||||
if (cfg.fps) document.getElementById('fps').value = cfg.fps;
|
||||
if (cfg.rotation) document.getElementById('rotation').value = cfg.rotation;
|
||||
} catch(e) {}
|
||||
updateDash();
|
||||
setInterval(updateDash,5000);
|
||||
|
||||
Reference in New Issue
Block a user