Files
ytLlive/ViewModels/MainViewModel.cs
T

154 lines
4.4 KiB
C#

using System.Collections.ObjectModel;
using System.Windows.Input;
using ytLive.Helpers;
using ytLive.Models;
using ytLive.Services;
namespace ytLive.ViewModels;
public class MainViewModel : ViewModelBase
{
private readonly YouTubeAuthService _youtubeAuth;
private readonly YouTubeStreamService _youtubeStream;
private readonly YouTubeChatService _youtubeChat;
private Scene? _activeScene;
private StreamStatus _streamStatus = StreamStatus.Offline;
private StreamHealth _currentHealth = new();
private string _streamTitle = string.Empty;
private string _streamKey = string.Empty;
private bool _isYouTubeConnected;
public ObservableCollection<Scene> Scenes { get; } = new();
public ObservableCollection<ChatMessage> ChatMessages { get; } = new();
public Scene? ActiveScene
{
get => _activeScene;
set => SetProperty(ref _activeScene, value);
}
public StreamStatus StreamStatus
{
get => _streamStatus;
set
{
if (SetProperty(ref _streamStatus, value))
{
OnPropertyChanged(nameof(IsOffline));
OnPropertyChanged(nameof(IsLive));
OnPropertyChanged(nameof(ShowGoLive));
}
}
}
public bool IsOffline => StreamStatus == StreamStatus.Offline;
public bool IsLive => StreamStatus == StreamStatus.Streaming;
public StreamHealth CurrentHealth
{
get => _currentHealth;
set => SetProperty(ref _currentHealth, value);
}
public string StreamTitle
{
get => _streamTitle;
set => SetProperty(ref _streamTitle, value);
}
public string StreamKey
{
get => _streamKey;
set => SetProperty(ref _streamKey, value);
}
public bool IsYouTubeConnected
{
get => _isYouTubeConnected;
set
{
if (SetProperty(ref _isYouTubeConnected, value))
{
OnPropertyChanged(nameof(ShowConnect));
OnPropertyChanged(nameof(ShowGoLive));
}
}
}
public bool ShowConnect => !IsYouTubeConnected;
public bool ShowGoLive => IsYouTubeConnected && IsOffline;
// Commands
public ICommand AddSceneCommand { get; }
public ICommand RemoveSceneCommand { get; }
public ICommand ConnectCommand { get; }
public ICommand GoLiveCommand { get; }
public ICommand EndStreamCommand { get; }
public MainViewModel()
{
_youtubeAuth = new YouTubeAuthService("", ""); // TODO: load from config
_youtubeStream = new YouTubeStreamService(_youtubeAuth);
_youtubeChat = new YouTubeChatService(_youtubeAuth);
_youtubeChat.MessageReceived += OnChatMessageReceived;
AddSceneCommand = new RelayCommand(_ => AddScene());
RemoveSceneCommand = new RelayCommand(scene => RemoveScene(scene as Scene));
ConnectCommand = new RelayCommand(_ => ConnectYouTube());
GoLiveCommand = new RelayCommand(_ => StartStream(), _ => IsYouTubeConnected && IsOffline);
EndStreamCommand = new RelayCommand(_ => StopStream(), _ => IsLive);
// Start with a default scene
AddScene("Scene 1");
}
private void AddScene(string? name = null)
{
var scene = new Scene { Name = name ?? $"Scene {Scenes.Count + 1}" };
Scenes.Add(scene);
ActiveScene = scene;
}
private void RemoveScene(Scene? scene)
{
if (scene == null) return;
Scenes.Remove(scene);
if (ActiveScene == scene)
ActiveScene = Scenes.FirstOrDefault();
}
private void OnChatMessageReceived(ChatMessage message)
{
System.Windows.Application.Current.Dispatcher.Invoke(() =>
{
ChatMessages.Add(message);
if (ChatMessages.Count > 500)
ChatMessages.RemoveAt(0);
});
}
private async void StartStream()
{
StreamStatus = StreamStatus.Connecting;
// TODO: Initialize capture pipeline, encode, and push to RTMP
// For now, simulate connection
await Task.Delay(500);
StreamStatus = StreamStatus.Streaming;
}
private void StopStream()
{
StreamStatus = StreamStatus.Offline;
}
private void ConnectYouTube()
{
// TODO: Launch OAuth2 flow in browser
// For now, this is a stub
IsYouTubeConnected = false;
}
}