Arrow button func,progress bar
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Media;
|
||||
using ModuleManager.Modules;
|
||||
|
||||
namespace ShadowStream.Obejeckte;
|
||||
//Quinn
|
||||
@@ -8,6 +9,8 @@ public class Catagory
|
||||
//basic code for catatgorys next
|
||||
public readonly string name;
|
||||
List<Item> items = new List<Item>();
|
||||
|
||||
StringConversions conv = new StringConversions();
|
||||
|
||||
public Catagory(string name)
|
||||
{
|
||||
@@ -44,10 +47,15 @@ public class Catagory
|
||||
int tmp = 0;
|
||||
foreach (Item item in items)
|
||||
{
|
||||
if(item.getLink().Contains(path))
|
||||
break;
|
||||
var link = item?.getLink();
|
||||
string localPath = new Uri(path).LocalPath;
|
||||
localPath = conv.ReplaceFirst(localPath, '\\', '/');
|
||||
Console.WriteLine($"Comparing link: '{link}' with path: '{localPath}'");
|
||||
if (!string.IsNullOrEmpty(link) && link.Contains(localPath, StringComparison.OrdinalIgnoreCase))
|
||||
return tmp;
|
||||
tmp++;
|
||||
}
|
||||
return tmp;
|
||||
return -1; // Not found
|
||||
}
|
||||
|
||||
}
|
@@ -33,13 +33,15 @@ public class Item
|
||||
{
|
||||
Content = isFoto ? "Show" : "Play",
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
Tag = path+"/"+type // Store path or any identifier
|
||||
Tag = path+"||"+type // Store path or any identifier
|
||||
};
|
||||
|
||||
if (clickHandler != null)
|
||||
playButton.Click += clickHandler;
|
||||
|
||||
this.isFoto = isFoto;
|
||||
|
||||
Console.WriteLine(path);
|
||||
}
|
||||
|
||||
|
||||
@@ -69,5 +71,10 @@ public class Item
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public Button getPlayButton()
|
||||
{
|
||||
return playButton;
|
||||
}
|
||||
|
||||
}
|
12
ShadowStream/Modules/StringConversions.cs
Normal file
12
ShadowStream/Modules/StringConversions.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace ModuleManager.Modules;
|
||||
|
||||
public class StringConversions
|
||||
{
|
||||
public string ReplaceFirst(string input, char from, char to)
|
||||
{
|
||||
int index = input.IndexOf(from);
|
||||
if (index < 0) return input;
|
||||
return input.Substring(0, index) + to + input.Substring(index + 1);
|
||||
}
|
||||
|
||||
}
|
@@ -2,6 +2,7 @@ using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Media.Imaging;
|
||||
using LibVLCSharp.Shared;
|
||||
using ModuleManager;
|
||||
@@ -9,38 +10,44 @@ using ModuleManager;
|
||||
public static class VideoFrameExtractor
|
||||
{
|
||||
public static BitmapImage GetFrame200(string videoPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
Core.Initialize();
|
||||
using var libVLC = new LibVLC("--no-xlib");
|
||||
using var media = new Media(libVLC, videoPath, FromType.FromPath);
|
||||
using var mp = new MediaPlayer(media);
|
||||
|
||||
mp.Play();
|
||||
|
||||
while (!mp.IsPlaying)
|
||||
Thread.Sleep(10);
|
||||
|
||||
// Seek to ~200th frame at 30 fps
|
||||
mp.Time = (long)((200.0 / 30.0) * 1000);
|
||||
Thread.Sleep(500);
|
||||
|
||||
if (!mp.IsPlaying)
|
||||
mp.Play();
|
||||
|
||||
Thread.Sleep(1000);
|
||||
|
||||
string path = Path.GetTempFileName() + ".png";
|
||||
|
||||
if (!mp.TakeSnapshot(0, path, 0, 0))
|
||||
throw new Exception("Snapshot failed.");
|
||||
|
||||
// Wait for snapshot file to be fully written and valid
|
||||
int attempts = 10;
|
||||
while (attempts-- > 0)
|
||||
using (var libVLC = new LibVLC("--no-xlib"))
|
||||
using (var media = new Media(libVLC, videoPath, FromType.FromPath))
|
||||
using (var mp = new MediaPlayer(media))
|
||||
{
|
||||
if (File.Exists(path) && new FileInfo(path).Length > 0)
|
||||
break;
|
||||
Thread.Sleep(100);
|
||||
mp.Play();
|
||||
|
||||
while (!mp.IsPlaying)
|
||||
Thread.Sleep(10);
|
||||
|
||||
// Seek to ~200th frame at 30 fps
|
||||
mp.Time = (long)((200.0 / 30.0) * 1000);
|
||||
Thread.Sleep(500);
|
||||
|
||||
if (!mp.IsPlaying)
|
||||
mp.Play();
|
||||
|
||||
Thread.Sleep(1000);
|
||||
|
||||
if (!mp.TakeSnapshot(0, path, 0, 0))
|
||||
throw new Exception("Snapshot failed.");
|
||||
|
||||
// Wait for snapshot file to be fully written and valid
|
||||
int attempts = 10;
|
||||
while (attempts-- > 0)
|
||||
{
|
||||
if (File.Exists(path) && new FileInfo(path).Length > 0)
|
||||
break;
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
|
||||
// ❗ Stop playback and dispose BEFORE trying to read the file
|
||||
mp.Stop();
|
||||
}
|
||||
|
||||
if (!File.Exists(path))
|
||||
@@ -50,46 +57,51 @@ public static class VideoFrameExtractor
|
||||
if (fileInfo.Length == 0)
|
||||
throw new Exception("Snapshot file is empty or corrupted.");
|
||||
|
||||
BitmapImage image = null;
|
||||
|
||||
try
|
||||
// Load BitmapImage on the UI thread
|
||||
BitmapImage image = Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
try
|
||||
{
|
||||
if (fs == null)
|
||||
throw new Exception("FileStream is null.");
|
||||
|
||||
image = new BitmapImage();
|
||||
|
||||
image.BeginInit();
|
||||
image.CacheOption = BitmapCacheOption.OnLoad;
|
||||
// Removed CreateOptions.IgnoreImageCache here to avoid ArgumentNullException
|
||||
image.StreamSource = fs ?? throw new Exception("StreamSource cannot be null.");
|
||||
fs.Position = 0;
|
||||
image.EndInit();
|
||||
image.Freeze();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
foreach (System.Windows.Window window in System.Windows.Application.Current.Windows)
|
||||
{
|
||||
if (window.IsActive && window is MainWindow mainWindow)
|
||||
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
mainWindow.ReciveErrorLog($"Error loading snapshot image from {path}: {ex}");
|
||||
break;
|
||||
var img = new BitmapImage();
|
||||
img.BeginInit();
|
||||
img.CacheOption = BitmapCacheOption.OnLoad;
|
||||
img.DecodePixelWidth = 150;
|
||||
img.DecodePixelHeight = 100;
|
||||
img.StreamSource = fs;
|
||||
fs.Position = 0;
|
||||
img.EndInit();
|
||||
img.Freeze();
|
||||
return img;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
foreach (System.Windows.Window window in System.Windows.Application.Current.Windows)
|
||||
{
|
||||
if (window.IsActive && window is MainWindow mainWindow)
|
||||
{
|
||||
mainWindow.ReciveErrorLog($"Error loading snapshot image from {path}: {ex}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception("Failed to load snapshot image.", ex);
|
||||
}
|
||||
throw new Exception("Failed to load snapshot image.", ex);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Async delayed delete of temp snapshot file (after 1 minute)
|
||||
DeleteFileLaterAsync(path);
|
||||
|
||||
return image!;
|
||||
return image;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static async void DeleteFileLaterAsync(string path, int delayMs = 60000)
|
||||
{
|
||||
|
Reference in New Issue
Block a user