secubox-openwrt/package/secubox/luci-app-media-flow/root/usr/bin/media-flow-collector
CyberMind-FR c536c9c0f8 feat: Fix and enhance Media Flow module (v0.5.0)
Major improvements to the Media Flow streaming detection module:

Backend (RPCD):
- Rewrite JSON handling to avoid subshell issues
- Use jq for all JSON processing (more reliable)
- Add delete_alert, clear_history, get_settings, set_settings methods
- Expand streaming service patterns (more services detected)
- Better bandwidth/quality estimation from netifyd data

Data Collection:
- Add media-flow-collector script for periodic data collection
- Add init script with cron job management
- History persists across service restarts
- Configurable retention period

Frontend:
- Remove unused Theme imports
- Fix history view to use correct field names
- Add Clear History button
- Add time period filter with refresh
- Improved table display with category icons

New streaming services detected:
- Video: Peacock, Paramount+, Crunchyroll, Funimation
- Audio: Amazon Music, YouTube Music
- Video calls: FaceTime, WhatsApp

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 18:02:39 +01:00

89 lines
3.3 KiB
Bash

#!/bin/sh
#
# Media Flow Data Collector
# Collects streaming service data from netifyd and stores in history
#
HISTORY_FILE="/tmp/media-flow-history.json"
MAX_ENTRIES=1000
LOCK_FILE="/tmp/media-flow-collector.lock"
# Streaming services patterns
STREAMING_PATTERN="netflix|youtube|disney|primevideo|amazon.*video|twitch|hulu|hbo|vimeo|peacock|paramount|crunchyroll|funimation|spotify|apple.*music|deezer|soundcloud|tidal|pandora|amazon.*music|youtube.*music|zoom|teams|meet|discord|skype|webex|facetime|whatsapp"
# Check if already running
if [ -f "$LOCK_FILE" ]; then
pid=$(cat "$LOCK_FILE")
if kill -0 "$pid" 2>/dev/null; then
exit 0
fi
fi
echo $$ > "$LOCK_FILE"
trap "rm -f $LOCK_FILE" EXIT
# Check if enabled
enabled=$(uci -q get media_flow.global.enabled 2>/dev/null || echo "1")
[ "$enabled" != "1" ] && exit 0
# Check if netifyd is running
pgrep -x netifyd > /dev/null 2>&1 || exit 0
# Initialize history file
[ ! -f "$HISTORY_FILE" ] && echo '[]' > "$HISTORY_FILE"
# Get current flows from netifyd
if [ -f /var/run/netifyd/status.json ]; then
timestamp=$(date -Iseconds)
# Extract streaming flows and format as history entries
new_entries=$(jq -c --arg ts "$timestamp" '
.flows // [] |
[.[] |
select(.detected_application != null and .detected_application != "") |
select(.detected_application | test("'"$STREAMING_PATTERN"'"; "i")) |
{
timestamp: $ts,
app: .detected_application,
client: (.local_ip // .src_ip // "unknown"),
bandwidth: (if .total_packets > 0 and .duration > 0 then
((.total_bytes * 8) / 1000 / .duration) | floor
else 0 end),
duration: (.duration // 0 | floor),
quality: (if .total_packets > 0 and .duration > 0 then
(if ((.total_bytes * 8) / 1000 / .duration) < 1000 then "SD"
elif ((.total_bytes * 8) / 1000 / .duration) < 3000 then "HD"
elif ((.total_bytes * 8) / 1000 / .duration) < 8000 then "FHD"
else "4K" end)
else "SD" end),
category: (if (.detected_application | test("netflix|youtube|disney|primevideo|twitch|hulu|hbo|vimeo"; "i")) then "video"
elif (.detected_application | test("spotify|apple.*music|deezer|soundcloud|tidal"; "i")) then "audio"
elif (.detected_application | test("zoom|teams|meet|discord|skype|webex"; "i")) then "visio"
else "other" end),
bytes: (.total_bytes // 0)
}
] |
# Only include flows with significant duration (> 10 seconds)
[.[] | select(.duration > 10)]
' /var/run/netifyd/status.json 2>/dev/null)
# If we have new entries, merge with history
if [ -n "$new_entries" ] && [ "$new_entries" != "[]" ] && [ "$new_entries" != "null" ]; then
# Merge and deduplicate (by client+app combination within same minute)
jq -c --argjson new "$new_entries" '
. + $new |
# Keep only last MAX_ENTRIES
.[-'"$MAX_ENTRIES"':]
' "$HISTORY_FILE" > "${HISTORY_FILE}.tmp" 2>/dev/null && mv "${HISTORY_FILE}.tmp" "$HISTORY_FILE"
fi
fi
# Clean old entries based on retention (days)
retention=$(uci -q get media_flow.global.history_retention 2>/dev/null || echo "7")
if [ "$retention" -gt 0 ] 2>/dev/null; then
cutoff_date=$(date -d "$retention days ago" -Iseconds 2>/dev/null || date -Iseconds)
jq -c --arg cutoff "$cutoff_date" '[.[] | select(.timestamp >= $cutoff)]' "$HISTORY_FILE" > "${HISTORY_FILE}.tmp" 2>/dev/null && mv "${HISTORY_FILE}.tmp" "$HISTORY_FILE"
fi
exit 0