TASK 21 Increment A: media-source model + persistence (schema migration + round-trip test)
SourceType.MediaSource added; MediaSourceType (Video/Audio) and MediaPlaybackState (Stopped/Playing/Paused) enums. Source gains MediaPath, MediaIsLooping, MediaVolume (0-1 clamped), MediaPlaybackState. LayoutStore: MigrateSourceTable adds 4 guarded ALTERs (MediaPath, MediaIsLooping, MediaVolume, MediaPlaybackState); SELECT appends indices 26-29, INSERT adds 4 columns + params. Round-trip test MediaSource_Config_Survives_Save_And_Reload passes. Build 0 warnings, 245/247 tests (2 known pre-existing). Gated on creator run for later integration (ffmpeg).
This commit is contained in:
+45
-3
@@ -281,6 +281,32 @@ public class LayoutStore : IDisposable
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// TASK 21: Media source (video/audio file playback)
|
||||
if (!columns.Contains("MediaPath"))
|
||||
{
|
||||
using var cmd = _connection.CreateCommand();
|
||||
cmd.CommandText = "ALTER TABLE Source ADD COLUMN MediaPath TEXT;";
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
if (!columns.Contains("MediaIsLooping"))
|
||||
{
|
||||
using var cmd = _connection.CreateCommand();
|
||||
cmd.CommandText = "ALTER TABLE Source ADD COLUMN MediaIsLooping INTEGER NOT NULL DEFAULT 0;";
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
if (!columns.Contains("MediaVolume"))
|
||||
{
|
||||
using var cmd = _connection.CreateCommand();
|
||||
cmd.CommandText = "ALTER TABLE Source ADD COLUMN MediaVolume REAL NOT NULL DEFAULT 1;";
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
if (!columns.Contains("MediaPlaybackState"))
|
||||
{
|
||||
using var cmd = _connection.CreateCommand();
|
||||
cmd.CommandText = "ALTER TABLE Source ADD COLUMN MediaPlaybackState TEXT NOT NULL DEFAULT 'Stopped';";
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// Rename legacy "Backdrop" display name to "Background" in existing rows
|
||||
using (var cmd = _connection.CreateCommand())
|
||||
{
|
||||
@@ -599,7 +625,7 @@ public class LayoutStore : IDisposable
|
||||
IsBackground, CaptureKey, ShowDesktop,
|
||||
ChatFontSize, ChatFontColor, ChatBackgroundColor, ChatMaxMessages,
|
||||
ChatShowTimestamps, ChatShowBadges, ChatMemberColor, ChatSuperChatColor,
|
||||
WebUri
|
||||
WebUri, MediaPath, MediaIsLooping, MediaVolume, MediaPlaybackState
|
||||
FROM Source ORDER BY SortOrder
|
||||
""";
|
||||
using var reader = cmd.ExecuteReader();
|
||||
@@ -637,6 +663,14 @@ public class LayoutStore : IDisposable
|
||||
ChatMemberColor = reader.IsDBNull(23) ? "#e94560" : reader.GetString(23),
|
||||
ChatSuperChatColor = reader.IsDBNull(24) ? "#eab308" : reader.GetString(24),
|
||||
WebUri = reader.IsDBNull(25) ? null : reader.GetString(25),
|
||||
MediaPath = reader.IsDBNull(26) ? null : reader.GetString(26),
|
||||
MediaIsLooping = reader.IsDBNull(27) ? false : reader.GetInt32(27) != 0,
|
||||
MediaVolume = reader.IsDBNull(28) ? 1.0 : reader.GetDouble(28),
|
||||
MediaPlaybackState = reader.IsDBNull(29)
|
||||
? MediaPlaybackState.Stopped
|
||||
: Enum.TryParse<MediaPlaybackState>(reader.GetString(29), out var ps)
|
||||
? ps
|
||||
: MediaPlaybackState.Stopped,
|
||||
};
|
||||
if (!sourcesByScene.TryGetValue(sceneId, out var list))
|
||||
sourcesByScene[sceneId] = list = new List<Source>();
|
||||
@@ -871,13 +905,13 @@ public class LayoutStore : IDisposable
|
||||
ClipShape, IsMirrored, IsBackground, CaptureKey, ShowDesktop, SortOrder,
|
||||
ChatFontSize, ChatFontColor, ChatBackgroundColor, ChatMaxMessages,
|
||||
ChatShowTimestamps, ChatShowBadges, ChatMemberColor, ChatSuperChatColor,
|
||||
WebUri)
|
||||
WebUri, MediaPath, MediaIsLooping, MediaVolume, MediaPlaybackState)
|
||||
VALUES ($id, $sceneId, $assetId, $type, $name, $isEnabled,
|
||||
$x, $y, $w, $h, $opacity, $monitor,
|
||||
$clip, $mirrored, $isBackground, $captureKey, $showDesktop, $sort,
|
||||
$chatFontSize, $chatFontColor, $chatBgColor, $chatMaxMsgs,
|
||||
$chatTimestamps, $chatBadges, $chatMemberColor, $chatSuperChatColor,
|
||||
$webUri)
|
||||
$webUri, $mediaPath, $mediaIsLooping, $mediaVolume, $mediaPlaybackState)
|
||||
""";
|
||||
cmd.Transaction = tx;
|
||||
var idP = cmd.Parameters.Add("$id", SqliteType.Text);
|
||||
@@ -907,6 +941,10 @@ public class LayoutStore : IDisposable
|
||||
var chatMemberColorP = cmd.Parameters.Add("$chatMemberColor", SqliteType.Text);
|
||||
var chatSuperChatColorP = cmd.Parameters.Add("$chatSuperChatColor", SqliteType.Text);
|
||||
var webUriP = cmd.Parameters.Add("$webUri", SqliteType.Text);
|
||||
var mediaPathP = cmd.Parameters.Add("$mediaPath", SqliteType.Text);
|
||||
var mediaIsLoopingP = cmd.Parameters.Add("$mediaIsLooping", SqliteType.Integer);
|
||||
var mediaVolumeP = cmd.Parameters.Add("$mediaVolume", SqliteType.Real);
|
||||
var mediaPlaybackStateP = cmd.Parameters.Add("$mediaPlaybackState", SqliteType.Text);
|
||||
|
||||
foreach (var scene in scenes)
|
||||
{
|
||||
@@ -941,6 +979,10 @@ public class LayoutStore : IDisposable
|
||||
chatMemberColorP.Value = source.ChatMemberColor;
|
||||
chatSuperChatColorP.Value = source.ChatSuperChatColor;
|
||||
webUriP.Value = (object?)source.WebUri ?? DBNull.Value;
|
||||
mediaPathP.Value = (object?)source.MediaPath ?? DBNull.Value;
|
||||
mediaIsLoopingP.Value = source.MediaIsLooping ? 1 : 0;
|
||||
mediaVolumeP.Value = source.MediaVolume;
|
||||
mediaPlaybackStateP.Value = source.MediaPlaybackState.ToString();
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user