mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-29 03:26:37 +08:00
e50282178d
Add an admin toggle playback.direct_only that offloads all decoding to the client. When enabled: - Emby PlaybackInfo no longer advertises SupportsTranscoding nor a TranscodingUrl, forcing Emby/Infuse/Yamby clients to direct play. - HLS endpoints refuse (ErrTranscodeDisabled) so the host never spawns ffmpeg. - Web player forces direct play, hides the HLS toggle, and surfaces a hint. Exposed via /system/info (direct_play_only) and the Settings page. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
74 lines
2.2 KiB
Go
74 lines
2.2 KiB
Go
// Package handler — system metadata endpoints used by the React shell
|
|
// (footer "powered by", admin status panel, scheduled-task page).
|
|
//
|
|
// These mirror the Vue surface (/api/system/info, /api/system/status,
|
|
// /api/system/scheduler) so the React port can reuse the same calls.
|
|
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
"runtime"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/shirou/gopsutil/v3/cpu"
|
|
"github.com/shirou/gopsutil/v3/disk"
|
|
"github.com/shirou/gopsutil/v3/mem"
|
|
|
|
"github.com/ShukeBta/MediaStationGo/internal/service"
|
|
)
|
|
|
|
// startedAt is captured at first call so /system/status can report uptime
|
|
// without threading state through the container.
|
|
var startedAt = time.Now()
|
|
|
|
func systemInfoHandler(svc *service.Container) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
directOnly := false
|
|
if svc.Repo != nil && svc.Repo.Setting != nil {
|
|
if v, err := svc.Repo.Setting.Get(c.Request.Context(), service.PlaybackDirectOnlySettingKey); err == nil {
|
|
directOnly = service.ParseBoolSetting(v, false)
|
|
}
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"name": "MediaStationGo",
|
|
"version": "0.1.0",
|
|
"go": runtime.Version(),
|
|
"os": runtime.GOOS,
|
|
"arch": runtime.GOARCH,
|
|
"data_dir": svc.Cfg.App.DataDir,
|
|
"cache_dir": svc.Cfg.Cache.CacheDir,
|
|
"direct_play_only": directOnly,
|
|
})
|
|
}
|
|
}
|
|
|
|
func systemStatusHandler(svc *service.Container) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
out := gin.H{
|
|
"uptime_seconds": int64(time.Since(startedAt).Seconds()),
|
|
"goroutines": runtime.NumGoroutine(),
|
|
}
|
|
if usage, err := cpu.Percent(0, false); err == nil && len(usage) > 0 {
|
|
out["cpu_percent"] = usage[0]
|
|
}
|
|
if v, err := mem.VirtualMemory(); err == nil {
|
|
out["memory_used"] = v.Used
|
|
out["memory_total"] = v.Total
|
|
}
|
|
if d, err := disk.Usage(svc.Cfg.App.DataDir); err == nil {
|
|
out["disk_used"] = d.Used
|
|
out["disk_total"] = d.Total
|
|
}
|
|
c.JSON(http.StatusOK, out)
|
|
}
|
|
}
|
|
|
|
// systemSchedulerHandler is the read-only (non-admin) variant of
|
|
// /admin/scheduler — handy on user-facing dashboards.
|
|
func systemSchedulerHandler(svc *service.Container) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
c.JSON(http.StatusOK, gin.H{"jobs": svc.Scheduler.Status()})
|
|
}
|
|
}
|