Arrow button func,progress bar

This commit is contained in:
Elias Quinn 2025-06-17 12:42:39 +01:00
parent 9534ed3a8a
commit 40270573ab
49 changed files with 2288 additions and 446 deletions

View File

@ -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
}
}

View File

@ -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;
}
}

View 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);
}
}

View File

@ -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)
{

View File

@ -55,7 +55,9 @@
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\Pics\MusicD.jpeg" />
<Content Include="Resources\Pics\MusicD.jpeg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

View File

@ -149,17 +149,19 @@
HorizontalAlignment="Left"/>
<!-- PLAYER CONTROLS -->
<Slider Name="itemProgress" Panel.ZIndex="2" VerticalAlignment="Top" ValueChanged="ItemProgress_OnValueChanged" Grid.Row="2" Grid.Column="1" Padding="10"></Slider>
<ProgressBar Name="itemProgressVisual" Panel.ZIndex="1" Height="20" VerticalAlignment="Top" Grid.Row="2" Grid.Column="1" Padding="10"></ProgressBar>
<StackPanel Grid.Column="1" Grid.Row="2"
Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Center"
VerticalAlignment="Bottom"
Background="#222">
<TextBlock Text="Titel" Foreground="White" FontSize="16" Margin="10"/>
<Button Content="⏮" Width="40" Margin="10" Click="OnItemPriorButtonClick"/>
<Button Content="▶" Width="40" Margin="10" Click="OnItemPauseBtn_Click"/>
<Button Content="⏭" Width="40" Margin="10" Click="OnItemNextButtonClick"/>
<TextBlock Text="🔊" Foreground="White" VerticalAlignment="Center" Margin="10,0"/>
<Slider Width="100" Minimum="0" Maximum="100" Value="50" Margin="10" ValueChanged="RangeBase_OnValueChanged"/>
<Slider Name="vol" Width="100" Minimum="0" Maximum="100" Value="50" Margin="10" ValueChanged="RangeBase_OnValueChanged"/>
</StackPanel>
</Grid>
</Window>

View File

@ -1,4 +1,5 @@
using System.Drawing;
using System.Collections.Concurrent;
using System.Drawing;
using System.Text;
using System.Windows;
using System.Windows.Controls;
@ -20,11 +21,13 @@ using TagLib;
using ShadowStream.Modules;
using ShadowStream.ObjecktForJason;
using LibVLCSharp.Shared;
using ModuleManager.Modules;
using Brushes = System.Windows.Media.Brushes;
using Color = System.Windows.Media.Color;
using File = System.IO.File;
using Image = System.Drawing.Image;
using Path = System.IO.Path;
using System.Text.RegularExpressions;
namespace ModuleManager;
@ -55,11 +58,18 @@ public partial class MainWindow : Window
//root directory
List<string> dirs = new List<string>();
private int option =2;
private int option = 2;
int specificOption = 0;
string rootPath = "F:/";
string rootPath = "G:/";
FileScanner fileScanner;
//video player variables
public string _path ;
public string _category;
StringConversions stringConversions = new StringConversions();
#endregion
@ -68,7 +78,7 @@ public partial class MainWindow : Window
private LibVLC _libVLC;
private LibVLCSharp.Shared.MediaPlayer _mediaPlayer;
#endregion
//code start
public MainWindow()
@ -96,6 +106,8 @@ public partial class MainWindow : Window
VideoView.MediaPlayer = _mediaPlayer;
_mediaPlayer.Volume = Convert.ToInt32(vol.Value);
#endregion
#region only exdend. no remuving of code
@ -162,25 +174,21 @@ public partial class MainWindow : Window
#endregion
#region Click Methods
//video player variables
private string path;
private string _category;
//-_- warum klapt es nicht
private ProgressBar progressScann;
private void OnItemPlayButtonClick(object sender, RoutedEventArgs e)
{
if (sender is Button btn && btn.Tag is string filePath)
{
string[] parts = filePath.Split('/');
if (parts.Length == 2)
{
string left = parts[0]; // "first"
PlayVideo(left);
path = left;
_category = parts[1];
}
string[] parts = filePath.Split("||");
string left = parts[0];
PlayVideo(left);
}
}
private void OnItemNextButtonClick(object sender, RoutedEventArgs e)
{
setStrings();
switch (_category.ToLower())
{
case "muvie":
@ -197,15 +205,16 @@ public partial class MainWindow : Window
}
private void OnItemPriorButtonClick(object sender, RoutedEventArgs e)
{
switch (_category)
setStrings();
switch (_category.ToLower())
{
case "Muvie":
case "muvie":
videoArrows(ref Muvie,false); break;
case "Serie":
case "serie":
videoArrows(ref Serie,false);break;
case "Music":
case "music":
videoArrows(ref Music,false); break;
case "Photos":
case "photos":
videoArrows(ref Photo,false); break;
default:
break;
@ -231,136 +240,144 @@ public partial class MainWindow : Window
}
private async void scanButton_Click(object sender, RoutedEventArgs e)
{
try
{
Muvie.clear();
Serie.clear();
Music.clear();
Photo.clear();
log.Log("Scanning files...");
List<string> tmp = new List<string>();
switch (option)
{
try
{
Muvie.clear();
Serie.clear();
Music.clear();
Photo.clear();
log.Log("Scanning files...");
List<string> tmp = new List<string>();
switch (option)
case 0:
foreach (var VARIABLE in dirs)
{
case 0:
foreach (var VARIABLE in dirs)
{
foreach (var tmp2 in await fileScanner.ScanDriveParallel(VARIABLE))
{
tmp.Add(tmp2);
}
}
break;
case 1:
foreach (var VARIABLE in await fileScanner.ScanDriveParallel(dirs[specificOption]))
{
tmp.Add(VARIABLE);
}
break;
case 2:
foreach (var VARIABLE in await fileScanner.ScanDriveParallel(rootPath))
{
tmp.Add(VARIABLE);
}
break;
var scanResult = await fileScanner.ScanDriveParallel(VARIABLE);
tmp.AddRange(scanResult);
}
log.Log($"Total scanned files: {tmp.Count}");
var classifier = new FileClassifier();
var (musicFiles, videoFiles, photoFiles) = await classifier.ClassifyFilesAsync(tmp, suportedMusicFiles, suportedVidioFiles, suportedPhotoFiles);
var separator = new VideoSeparator();
var (series, movies) = await separator.SeparateVideosAsync(videoFiles);
log.Log($"musicFiles count: {musicFiles.Count}");
log.Log($"videoFiles count: {videoFiles.Count}");
log.Log($"photoFiles count: {photoFiles.Count}");
log.Log($"series count: {series.Count}");
log.Log($"movies count: {movies.Count}");
videoFiles = null;
log.Log("files sorted");
// Prepare JSON lists
List<locJason> muviesJS = new List<locJason>();
List<locJason> seriesJS = new List<locJason>();
List<locJason> photosJS = new List<locJason>();
List<locJason> mucicJS = new List<locJason>();
JasonToString jasonToString = new JasonToString();
foreach (var VARIABLE in ItemCreater(movies, "Muvie", false))
{
Muvie.addItem(VARIABLE);
muviesJS.Add(new locJason
{
path = VARIABLE.getLink(),
imageData = jasonToString.BitmapToBase64String(BitmapConversions.BitmapImageToBitmap(VARIABLE.getImage())),
type = VARIABLE.getType()
});
}
foreach (var VARIABLE in ItemCreater(series, "Serie", false))
{
Serie.addItem(VARIABLE);
seriesJS.Add(new locJason
{
path = VARIABLE.getLink(),
imageData = jasonToString.BitmapToBase64String(BitmapConversions.BitmapImageToBitmap(VARIABLE.getImage())),
type = VARIABLE.getType()
});
}
foreach (var VARIABLE in ItemCreater(photoFiles, "Photo", true))
{
Photo.addItem(VARIABLE);
photosJS.Add(new locJason
{
path = VARIABLE.getLink(),
imageData = jasonToString.BitmapToBase64String(BitmapConversions.BitmapImageToBitmap(VARIABLE.getImage())),
type = VARIABLE.getType()
});
}
foreach (var VARIABLE in ItemCreater(musicFiles, "Music", false, true))
{
Music.addItem(VARIABLE);
mucicJS.Add(new locJason
{
path = VARIABLE.getLink(),
imageData = jasonToString.BitmapToBase64String(BitmapConversions.BitmapImageToBitmap(VARIABLE.getImage())),
type = VARIABLE.getType()
});
}
log.Log("scan finished");
Jason_Writer jason_Writer = new Jason_Writer();
List<Task> tasks = new List<Task>
{
jason_Writer.SaveList("Muvies", muviesJS),
jason_Writer.SaveList("Series", seriesJS),
jason_Writer.SaveList("Photos", photosJS),
jason_Writer.SaveList("Music", mucicJS)
};
await Task.WhenAll(tasks);
mucicJS = null;
seriesJS = null;
photosJS = null;
MenueItems();
MessageBox.Show("Scan finished");
}
catch (Exception ex)
{
MessageBox.Show($"An error occurred during scanning:\n\n{ex.ToString()}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
log.Error($"An error occurred during scanning:\n\n{ex.ToString()}");
}
break;
case 1:
var scanResult1 = await fileScanner.ScanDriveParallel(dirs[specificOption]);
tmp.AddRange(scanResult1);
break;
case 2:
var scanResult2 = await fileScanner.ScanDriveParallel(rootPath);
tmp.AddRange(scanResult2);
break;
}
log.Log($"Total scanned files: {tmp.Count}");
var classifier = new FileClassifier();
var (musicFiles, videoFiles, photoFiles) = await classifier.ClassifyFilesAsync(tmp, suportedMusicFiles, suportedVidioFiles, suportedPhotoFiles);
var separator = new VideoSeparator();
var (series, movies) = await separator.SeparateVideosAsync(videoFiles);
log.Log($"musicFiles count: {musicFiles.Count}");
log.Log($"videoFiles count: {videoFiles.Count}");
log.Log($"photoFiles count: {photoFiles.Count}");
log.Log($"series count: {series.Count}");
log.Log($"movies count: {movies.Count}");
progressScann = new ProgressBar("ImageGen",musicFiles.Count + videoFiles.Count + photoFiles.Count);
progressScann.Show();
videoFiles = null;
log.Log("files sorted");
// Prepare JSON lists
List<locJason> muviesJS = new List<locJason>();
List<locJason> seriesJS = new List<locJason>();
List<locJason> photosJS = new List<locJason>();
List<locJason> mucicJS = new List<locJason>();
JasonToString jasonToString = new JasonToString();
// Use async ItemCreaterAsync
var movieItems = await ItemCreater(movies, "Muvie", false);
foreach (var VARIABLE in movieItems)
{
Muvie.addItem(VARIABLE);
muviesJS.Add(new locJason
{
path = VARIABLE.getLink(),
imageData = jasonToString.BitmapToBase64String(BitmapConversions.BitmapImageToBitmap(VARIABLE.getImage())),
type = VARIABLE.getType()
});
}
var seriesItems = await ItemCreater(series, "Serie", false);
foreach (var VARIABLE in seriesItems)
{
Serie.addItem(VARIABLE);
seriesJS.Add(new locJason
{
path = VARIABLE.getLink(),
imageData = jasonToString.BitmapToBase64String(BitmapConversions.BitmapImageToBitmap(VARIABLE.getImage())),
type = VARIABLE.getType()
});
}
var photoItems = await ItemCreater(photoFiles, "Photo", true);
foreach (var VARIABLE in photoItems)
{
Photo.addItem(VARIABLE);
photosJS.Add(new locJason
{
path = VARIABLE.getLink(),
imageData = jasonToString.BitmapToBase64String(BitmapConversions.BitmapImageToBitmap(VARIABLE.getImage())),
type = VARIABLE.getType()
});
}
var musicItems = await ItemCreater(musicFiles, "Music", false, true);
foreach (var VARIABLE in musicItems)
{
Music.addItem(VARIABLE);
mucicJS.Add(new locJason
{
path = VARIABLE.getLink(),
imageData = jasonToString.BitmapToBase64String(BitmapConversions.BitmapImageToBitmap(VARIABLE.getImage())),
type = VARIABLE.getType()
});
}
log.Log("scan finished");
Jason_Writer jason_Writer = new Jason_Writer();
List<Task> tasks = new List<Task>
{
jason_Writer.SaveList("Muvies", muviesJS),
jason_Writer.SaveList("Series", seriesJS),
jason_Writer.SaveList("Photos", photosJS),
jason_Writer.SaveList("Music", mucicJS)
};
await Task.WhenAll(tasks);
// Clear lists to free memory
mucicJS = null;
seriesJS = null;
photosJS = null;
MenueItems();
progressScann.Hide();
MessageBox.Show("Scan finished");
}
catch (Exception ex)
{
MessageBox.Show($"An error occurred during scanning:\n\n{ex}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
log.Error($"An error occurred during scanning:\n\n{ex}");
}
}
#region Catagory btns
private void Home_OnClick(object sender, RoutedEventArgs e)
{
@ -372,6 +389,8 @@ public partial class MainWindow : Window
private void Musik_OnClick(object sender, RoutedEventArgs e)
{
Close_Player();
Name_of_Catagory_Text1.Visibility = Visibility.Collapsed;
ScrollContentHome.Visibility = Visibility.Collapsed;
ScrollContentCat.Visibility = Visibility.Visible;
Name_of_Catagory1.Visibility = Visibility.Collapsed;
@ -380,6 +399,8 @@ public partial class MainWindow : Window
private void Photo_OnClick(object sender, RoutedEventArgs e)
{
Close_Player();
Name_of_Catagory_Text1.Visibility = Visibility.Collapsed;
ScrollContentHome.Visibility = Visibility.Collapsed;
ScrollContentCat.Visibility = Visibility.Visible;
Name_of_Catagory1.Visibility = Visibility.Collapsed;
@ -388,6 +409,8 @@ public partial class MainWindow : Window
private void Video_OnClick(object sender, RoutedEventArgs e)
{
Close_Player();
Name_of_Catagory_Text1.Visibility = Visibility.Visible;
ScrollContentHome.Visibility = Visibility.Collapsed;
ScrollContentCat.Visibility = Visibility.Visible;
Name_of_Catagory1.Visibility = Visibility.Visible;
@ -400,97 +423,148 @@ public partial class MainWindow : Window
#region itemCreation
List<Item> ItemCreater(List<string> path, string type,bool isFoto)
async Task<List<Item>> ItemCreater(List<string> paths, string type, bool isFoto)
{
List<Item> items = new List<Item>();
foreach (var VARIABLE in path)
var semaphore = new SemaphoreSlim(Math.Max(1, Environment.ProcessorCount / 2));
var tasks = paths.Select(async path =>
{
BitmapImage frame200;
if(!isFoto)
frame200 = VideoFrameExtractor.GetFrame200(VARIABLE);
else
{
frame200 = new BitmapImage(new Uri(VARIABLE, UriKind.Absolute));
await semaphore.WaitAsync();
try
{
BitmapImage frame200 = null;
if (!isFoto)
{
frame200 = await Task.Run(() => VideoFrameExtractor.GetFrame200(path));
}
else
{
await Application.Current.Dispatcher.InvokeAsync(() =>
{
frame200 = new BitmapImage(new Uri(path, UriKind.Absolute));
frame200.DecodePixelWidth = 150;
frame200.DecodePixelHeight = 100;
});
}
Application.Current.Dispatcher.Invoke(() => progressScann.UpdateProgress(1));
return new Item(path, type, frame200, isFoto, OnItemPlayButtonClick);
}
items.Add(new Item(VARIABLE, type,frame200, isFoto,OnItemPlayButtonClick));
}
finally
{
semaphore.Release();
}
}).ToList();
return items;
return (await Task.WhenAll(tasks)).ToList();
}
List<Item> ItemCreater(List<string> paths, string type, bool isFoto, bool Music)
public async Task<List<Item>> ItemCreater(List<string> paths, string type, bool isFoto, bool isMusic = false)
{
var itemsBag = new ConcurrentBag<Item>();
var workQueue = new ConcurrentQueue<string>(paths);
int maxWorkers = Math.Max(1, Environment.ProcessorCount / 2);
var workers = new List<Task>();
// Prepare default image for music if needed
BitmapImage defaultImage = null;
if (isMusic)
{
List<Item> items = new List<Item>();
string baseDir = AppDomain.CurrentDomain.BaseDirectory;
string imagePath = Path.Combine(baseDir,"Resources", "Pics", "MusicD.jpeg");
string imagePath = System.IO.Path.Combine(baseDir, "Resources", "Pics", "MusicD.jpeg");
BitmapImage defaultImage;
if (File.Exists(imagePath))
if (System.IO.File.Exists(imagePath))
{
defaultImage = new BitmapImage(new Uri(imagePath));
defaultImage.Freeze();
await Application.Current.Dispatcher.InvokeAsync(() =>
{
defaultImage = new BitmapImage(new Uri(imagePath));
defaultImage.DecodePixelWidth = 150;
defaultImage.DecodePixelHeight = 100;
defaultImage.Freeze();
});
}
else
{
//this case schould never be called. its to prevent code from breaking because of unautorised muving of musicD!!
MessageBox.Show($"Default image not found at: {imagePath}");
// Create a blank 100x100 transparent BitmapImage fallback
int width = 100;
int height = 100;
int dpi = 96;
var pixelFormat = PixelFormats.Pbgra32;
int rawStride = (width * pixelFormat.BitsPerPixel + 7) / 8;
byte[] rawImage = new byte[rawStride * height]; // all zero = transparent
var bitmap = BitmapSource.Create(width, height, dpi, dpi, pixelFormat, null, rawImage, rawStride);
bitmap.Freeze();
defaultImage = new BitmapImage();
defaultImage = null;
}
}
foreach (var filePath in paths)
for (int i = 0; i < maxWorkers; i++)
{
workers.Add(Task.Run(async () =>
{
BitmapImage bitmapImage = defaultImage;
try
while (workQueue.TryDequeue(out var filePath))
{
var file = TagLib.File.Create(filePath);
if (file.Tag.Pictures.Length > 0)
{
var pic = file.Tag.Pictures[0];
using (var ms = new MemoryStream(pic.Data.Data))
{
var img = new BitmapImage();
img.BeginInit();
img.CacheOption = BitmapCacheOption.OnLoad;
img.StreamSource = ms;
img.EndInit();
img.Freeze();
BitmapImage bitmapImage = null;
bitmapImage = img;
try
{
if (isMusic)
{
bitmapImage = defaultImage;
try
{
var file = TagLib.File.Create(filePath);
if (file.Tag.Pictures.Length > 0)
{
var pic = file.Tag.Pictures[0];
var ms = new System.IO.MemoryStream(pic.Data.Data);
await Application.Current.Dispatcher.InvokeAsync(() =>
{
var img = new BitmapImage();
img.BeginInit();
img.CacheOption = BitmapCacheOption.OnLoad;
ms.Position = 0;
img.StreamSource = ms;
img.EndInit();
img.Freeze();
img.DecodePixelWidth = 150;
img.DecodePixelHeight = 100;
bitmapImage = img;
});
ms.Dispose();
}
}
catch
{
// keep defaultImage on failure
}
}
}
}
catch
{
// keep defaultImage if anything fails
}
catch
{
// fallback: bitmapImage stays null or default
}
items.Add(new Item(filePath, type, bitmapImage, isFoto,OnItemPlayButtonClick));
}
// Create Item on UI thread because it creates UI controls internally
Item newItem = null;
await Application.Current.Dispatcher.InvokeAsync(() =>
{
newItem = new Item(filePath, type, bitmapImage, isFoto, OnItemPlayButtonClick);
});
return items;
itemsBag.Add(newItem);
Application.Current.Dispatcher.Invoke(() => progressScann.UpdateProgress(1));
}
}));
}
await Task.WhenAll(workers);
return itemsBag.ToList();
}
#endregion
#region Comunication
public void addFavorit(ref Item item)
{
favorites.SharedRefs.Add(item);
@ -505,35 +579,96 @@ public partial class MainWindow : Window
VideoView.Visibility = Visibility.Visible;
var media = new Media(_libVLC, filePath, FromType.FromPath);
_mediaPlayer.Play(media);
videoSliderInit(media.Duration/1000);
}
public void setStrings()
{
#region type?
var currentMedia = _mediaPlayer?.Media;
if (currentMedia != null)
{
var mrl = currentMedia.Mrl; // This is the media resource locator
_path = new Uri(mrl).LocalPath;;
_path = stringConversions.ReplaceFirst(_path, '/', '\\');
Console.WriteLine("Now Playing Path: " + _path);
}
if (_mediaPlayer.IsPlaying)
{
_mediaPlayer.Stop();
}
if (suportedMusicFiles.Any(keyword => _path.Contains(keyword, StringComparison.OrdinalIgnoreCase)))
{
_category = "music";
}
else if (suportedPhotoFiles.Any(keyword => _path.Contains(keyword, StringComparison.OrdinalIgnoreCase)))
{
_category = "photos";
}
else
{
if (Regex.IsMatch(_path, @"\b(E|EP|Ep|e|ep)\d+\b", RegexOptions.IgnoreCase))
{
_category = "serie";
}
else
{
_category = "muvie";
}
}
log.Log($"replacing: {_path} from {_category}");
#endregion
}
public void videoArrows(ref Catagory catagory, bool next)
{
catagory = catagory as Catagory;
if (catagory == null || catagory.getAllItems() == null)
var items = catagory?.getAllItems();
if (catagory == null || items == null)
{
MessageBox.Show("Category or items are null");
return;
}
int tmp = catagory.contains(path);
Media media;
if (next && catagory.getAllItems().Count > tmp)
int tmp = catagory.contains(_path);
if (tmp == -1 || tmp >= items.Count)
{
media = new Media(_libVLC, catagory.getAllItems()[tmp + 1].getLink(), FromType.FromPath);
MessageBox.Show("Current item not found in category");
return;
}
else
Media media = null;
if (next)
{
if(tmp >1)
media = new Media(_libVLC, catagory.getAllItems()[tmp - 1].getLink(), FromType.FromPath);
else
if (tmp + 1 < items.Count)
{
media = new Media(_libVLC, catagory.getAllItems()[tmp].getLink(), FromType.FromPath);
var link = items[tmp + 1]?.getLink();
if (!string.IsNullOrEmpty(link))
media = new Media(_libVLC, link, FromType.FromPath);
}
}
if(media!=null)
if (!next)
{
int newIndex = (tmp - 1 >= 0) ? tmp - 1 : items.Count - 1; // wrap around
var link = items[newIndex]?.getLink();
Console.WriteLine(link);
if (!string.IsNullOrEmpty(link))
media = new Media(_libVLC, link, FromType.FromPath);
}
if (media != null)
_mediaPlayer.Play(media);
else
MessageBox.Show("Could not load media. Media or link is null.");
}
private void Close_Player()
{
@ -676,7 +811,10 @@ public partial class MainWindow : Window
var series = await jason_Writer.LoadListAsync("Series");
var photos = await jason_Writer.LoadListAsync("Photos");
var music = await jason_Writer.LoadListAsync("Music");
progressScann = new ProgressBar("Reading saved data",muvies.Count+series.Count+photos.Count+music.Count);
progressScann.Show();
List<Item> MuvieItems = CreateItemsFromJson(muvies);
List<Item> SerieItems = CreateItemsFromJson(series);
List<Item> PhotoItems = CreateItemsFromJson(photos, isPhoto: true);
@ -688,7 +826,7 @@ public partial class MainWindow : Window
Music.addItems(MusicItems);
MenueItems(); // Re-populate the UI
progressScann.Hide();
log.Log("Loaded saved data from JSON.");
}
catch (Exception ex)
@ -745,6 +883,10 @@ public partial class MainWindow : Window
}
items.Add(new Item(loc.path, loc.type, bitmapImage, isPhoto, OnItemPlayButtonClick));
Application.Current.Dispatcher.Invoke(() =>
{
progressScann.UpdateProgress(1);
});
}
return items;
@ -771,4 +913,34 @@ public partial class MainWindow : Window
#endregion
#region progress slider
private void ItemProgress_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (itemProgress.IsMouseOver)
{
ProgressBarValueChange();
}
}
private void ItemProgress_OnValueChanged(long timeStap)
{
itemProgress.Value = timeStap;
ProgressBarValueChange();
}
private void ProgressBarValueChange()
{
itemProgressVisual.Value = itemProgress.Value;
_mediaPlayer.Time = Convert.ToInt64(itemProgress.Value) * 1000; // convert to milliseconds
}
private void videoSliderInit(long timeStap)
{
itemProgress.Maximum = timeStap;
itemProgressVisual.Maximum = timeStap;
itemProgress.Minimum = 0;
itemProgressVisual.Minimum = 0;
}
#endregion
}

View File

@ -0,0 +1,35 @@
using System.Windows;
namespace ModuleManager;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
//Quinn and Reda and Yazan
public partial class ProgressBar : Window
{ //quinn
private int currentValue = 0;
public ProgressBar(string title,int maxValue)
{
InitializeComponent();
lab.Content = title;
Bar.Maximum = maxValue;
Bar.Minimum = 0;
}
//Quinn
public void UpdateProgress(int value)
{
//force update and enshure ui thread updates
Dispatcher.Invoke(() =>
{
currentValue += value;
if (currentValue > Bar.Maximum)
currentValue = (int)Bar.Maximum;
Bar.Value = currentValue;
Bar.Dispatcher.Invoke(() => { }, System.Windows.Threading.DispatcherPriority.Render);
});
}
}

View File

@ -0,0 +1,16 @@
<Window x:Class="ModuleManager.ProgressBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vlc="clr-namespace:LibVLCSharp.WPF;assembly=LibVLCSharp.WPF"
mc:Ignorable="d"
Title="ProgressBar" ResizeMode="NoResize"
SizeToContent="WidthAndHeight"
Background="DarkGray"
Topmost="True">
<DockPanel Margin="10">
<Label Name="lab" DockPanel.Dock="Top" Content="Labtext" VerticalAlignment="Center" HorizontalContentAlignment="Center" HorizontalAlignment="Center"></Label>
<ProgressBar Name="Bar" Background="Red" Height="20" Width="500"></ProgressBar>
</DockPanel>
</Window>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("ShadowStream")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+afe5d2f5ff1f6bedbf81fd0a6fcf377b5186c062")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+9534ed3a8a64dfd1c23d61f834b73146bfbe4362")]
[assembly: System.Reflection.AssemblyProductAttribute("ShadowStream")]
[assembly: System.Reflection.AssemblyTitleAttribute("ShadowStream")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@ -1 +1 @@
6bde34b2e5e75e632a9f05946a429aa1a2730ff7ebb7bdb5c8d132255bde2008
08a4cb3ea356bf6629d875e5247129db46f3d34a13e6e1d5aa0382365dadd8ea

View File

@ -1 +1 @@
25fbc983509f91ec12ae31c845e2b078a52bd2cc2bfd1a54d4399d98c002f139
3da02ab8c2fa5cc0d3b567a28eaf9c3b879b900b2521902a5f3c91bc1daec065

View File

@ -1769,3 +1769,6 @@ C:\Users\bib\Desktop\vpr\pull from pc\mediaverwaltung\ShadowStream\obj\Debug\net
C:\Users\bib\Desktop\vpr\pull from pc\mediaverwaltung\ShadowStream\obj\Debug\net8.0-windows\Views\LogIn.g.cs
C:\Users\bib\Desktop\vpr\pull from pc\mediaverwaltung\ShadowStream\obj\Debug\net8.0-windows\Views\MainWindow.g.cs
C:\Users\bib\Desktop\vpr\pull from pc\mediaverwaltung\ShadowStream\obj\Debug\net8.0-windows\Resources\LogHelper\LogWindow.baml
C:\Users\bib\Desktop\vpr\pull from pc\mediaverwaltung\ShadowStream\obj\Debug\net8.0-windows\Views\ProgressBar.baml
C:\Users\bib\Desktop\vpr\pull from pc\mediaverwaltung\ShadowStream\obj\Debug\net8.0-windows\Views\ProgressBar.g.cs
C:\Users\bib\Desktop\vpr\pull from pc\mediaverwaltung\ShadowStream\bin\Debug\net8.0-windows\Resources\Pics\MusicD.jpeg

View File

@ -1 +1 @@
{"documents":{"C:\\Users\\bib\\Desktop\\vpr\\pull from pc\\mediaverwaltung\\*":"https://gitlab.com/NotMoReda1/mediaverwaltung/-/raw/afe5d2f5ff1f6bedbf81fd0a6fcf377b5186c062/*"}}
{"documents":{"C:\\Users\\bib\\Desktop\\vpr\\pull from pc\\mediaverwaltung\\*":"https://gitlab.com/NotMoReda1/mediaverwaltung/-/raw/9534ed3a8a64dfd1c23d61f834b73146bfbe4362/*"}}

View File

@ -7,6 +7,7 @@
// </auto-generated>
//------------------------------------------------------------------------------
[assembly: System.Windows.Resources.AssemblyAssociatedContentFileAttribute("resources/pics/musicd.jpeg")]
[assembly: System.Windows.Resources.AssemblyAssociatedContentFileAttribute("libvlc.dll")]
[assembly: System.Windows.Resources.AssemblyAssociatedContentFileAttribute("libvlc.lib")]
[assembly: System.Windows.Resources.AssemblyAssociatedContentFileAttribute("libvlccore.dll")]

View File

@ -10,11 +10,11 @@ none
false
TRACE;DEBUG;NET;NET8_0;NETCOREAPP
C:\Users\bib\Desktop\vpr\pull from pc\mediaverwaltung\ShadowStream\App.xaml
3-1800985124
8442008295505
16-532759807
4-57806783
8451318677653
18-1734813481
206663139284
Resources\LogHelper\LogWindow.xaml;Views\LogIn.xaml;Views\MainWindow.xaml;
Resources\LogHelper\LogWindow.xaml;Views\LogIn.xaml;Views\MainWindow.xaml;Views\ProgressBar.xaml;
False

View File

@ -1,4 +1,4 @@
#pragma checksum "..\..\..\..\Views\MainWindow.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "671655137D3BB5DA122D40D6179CD34D64E17E55"
#pragma checksum "..\..\..\..\Views\MainWindow.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "9FF6E2F3C9F46B49B955E66EB2F74EF7FC7D84DA"
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
@ -144,6 +144,30 @@ namespace ModuleManager {
#line default
#line hidden
#line 152 "..\..\..\..\Views\MainWindow.xaml"
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal System.Windows.Controls.Slider itemProgress;
#line default
#line hidden
#line 153 "..\..\..\..\Views\MainWindow.xaml"
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal System.Windows.Controls.ProgressBar itemProgressVisual;
#line default
#line hidden
#line 164 "..\..\..\..\Views\MainWindow.xaml"
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal System.Windows.Controls.Slider vol;
#line default
#line hidden
private bool _contentLoaded;
/// <summary>
@ -254,33 +278,46 @@ namespace ModuleManager {
this.Name_of_Catagory1 = ((System.Windows.Controls.WrapPanel)(target));
return;
case 19:
this.itemProgress = ((System.Windows.Controls.Slider)(target));
#line 158 "..\..\..\..\Views\MainWindow.xaml"
((System.Windows.Controls.Button)(target)).Click += new System.Windows.RoutedEventHandler(this.OnItemPriorButtonClick);
#line 152 "..\..\..\..\Views\MainWindow.xaml"
this.itemProgress.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(this.ItemProgress_OnValueChanged);
#line default
#line hidden
return;
case 20:
#line 159 "..\..\..\..\Views\MainWindow.xaml"
((System.Windows.Controls.Button)(target)).Click += new System.Windows.RoutedEventHandler(this.OnItemPauseBtn_Click);
#line default
#line hidden
this.itemProgressVisual = ((System.Windows.Controls.ProgressBar)(target));
return;
case 21:
#line 160 "..\..\..\..\Views\MainWindow.xaml"
((System.Windows.Controls.Button)(target)).Click += new System.Windows.RoutedEventHandler(this.OnItemNextButtonClick);
((System.Windows.Controls.Button)(target)).Click += new System.Windows.RoutedEventHandler(this.OnItemPriorButtonClick);
#line default
#line hidden
return;
case 22:
#line 161 "..\..\..\..\Views\MainWindow.xaml"
((System.Windows.Controls.Button)(target)).Click += new System.Windows.RoutedEventHandler(this.OnItemPauseBtn_Click);
#line default
#line hidden
return;
case 23:
#line 162 "..\..\..\..\Views\MainWindow.xaml"
((System.Windows.Controls.Slider)(target)).ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(this.RangeBase_OnValueChanged);
((System.Windows.Controls.Button)(target)).Click += new System.Windows.RoutedEventHandler(this.OnItemNextButtonClick);
#line default
#line hidden
return;
case 24:
this.vol = ((System.Windows.Controls.Slider)(target));
#line 164 "..\..\..\..\Views\MainWindow.xaml"
this.vol.ValueChanged += new System.Windows.RoutedPropertyChangedEventHandler<double>(this.RangeBase_OnValueChanged);
#line default
#line hidden

View File

@ -0,0 +1,100 @@
#pragma checksum "..\..\..\..\Views\ProgressBar.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "C5F8D136A10AA2C7691934CA2591235EE8C3EA9B"
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using LibVLCSharp.WPF;
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Controls.Ribbon;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
using System.Windows.Media.TextFormatting;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Shell;
namespace ModuleManager {
/// <summary>
/// ProgressBar
/// </summary>
public partial class ProgressBar : System.Windows.Window, System.Windows.Markup.IComponentConnector {
#line 13 "..\..\..\..\Views\ProgressBar.xaml"
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal System.Windows.Controls.Label lab;
#line default
#line hidden
#line 14 "..\..\..\..\Views\ProgressBar.xaml"
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal System.Windows.Controls.ProgressBar Bar;
#line default
#line hidden
private bool _contentLoaded;
/// <summary>
/// InitializeComponent
/// </summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "8.0.13.0")]
public void InitializeComponent() {
if (_contentLoaded) {
return;
}
_contentLoaded = true;
System.Uri resourceLocater = new System.Uri("/ShadowStream;component/views/progressbar.xaml", System.UriKind.Relative);
#line 1 "..\..\..\..\Views\ProgressBar.xaml"
System.Windows.Application.LoadComponent(this, resourceLocater);
#line default
#line hidden
}
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "8.0.13.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
switch (connectionId)
{
case 1:
this.lab = ((System.Windows.Controls.Label)(target));
return;
case 2:
this.Bar = ((System.Windows.Controls.ProgressBar)(target));
return;
}
this._contentLoaded = true;
}
}
}

View File

@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("file finder test")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+afe5d2f5ff1f6bedbf81fd0a6fcf377b5186c062")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+9534ed3a8a64dfd1c23d61f834b73146bfbe4362")]
[assembly: System.Reflection.AssemblyProductAttribute("file finder test")]
[assembly: System.Reflection.AssemblyTitleAttribute("file finder test")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@ -1 +1 @@
c969ed8ee648fb9fdb1f3d9435801aa0c044aa8da181b83fe997ecb745d992fd
ccf60afd49f1b21d86879c8dd557d8a1506227e467e95e993b2748760c8d7e23

View File

@ -1 +1 @@
{"documents":{"C:\\Users\\bib\\Desktop\\vpr\\pull from pc\\mediaverwaltung\\*":"https://gitlab.com/NotMoReda1/mediaverwaltung/-/raw/afe5d2f5ff1f6bedbf81fd0a6fcf377b5186c062/*"}}
{"documents":{"C:\\Users\\bib\\Desktop\\vpr\\pull from pc\\mediaverwaltung\\*":"https://gitlab.com/NotMoReda1/mediaverwaltung/-/raw/9534ed3a8a64dfd1c23d61f834b73146bfbe4362/*"}}