Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions samples/FFmpegView.AvaloniaDemo/App.axaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FFmpegView"
xmlns:vm="clr-namespace:FFmpegView.AvaloniaDemo.Models"
x:Class="FFmpegView.AvaloniaDemo.App">

<Application.DataTemplates>
<local:ViewLocator/>
</Application.DataTemplates>

<Application.Styles>
<FluentTheme Mode="Dark" />
<StyleInclude Source="/Styles/Icons.axaml"></StyleInclude>
</Application.Styles>

<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<vm:MainWindowViewModel x:Key="ViewModel" />
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
32 changes: 31 additions & 1 deletion samples/FFmpegView.AvaloniaDemo/App.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using FFmpegView.AvaloniaDemo.Models;
using FFmpegView.Bass;
using System;

Expand All @@ -14,14 +16,42 @@ public override void Initialize()
AvaloniaXamlLoader.Load(this);
BassCore.Initialize();
}

public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
desktop.MainWindow = new MainWindow();
{
desktop.MainWindow = new MainWindow()
{
DataContext = new MainWindowViewModel()
};
}

Console.WriteLine(FontManager.Current.DefaultFontFamilyName);
Console.WriteLine(FontManager.Current.PlatformImpl.GetDefaultFontFamilyName());
Console.WriteLine(string.Join(';', FontManager.Current.PlatformImpl.GetInstalledFontFamilyNames()));
base.OnFrameworkInitializationCompleted();
}

public static Window? MainWindow
{
get
{
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
return desktop.MainWindow;
}

return null;
}
}

public static MainWindowViewModel? ViewModel
{
get
{
return MainWindow?.DataContext as MainWindowViewModel;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.21" />
<PackageReference Include="Dove.Bass.Windows" Version="1.0.0" />
<PackageReference Include="Avalonia.Desktop" Version="0.10.18" />
<PackageReference Include="Avalonia.Desktop" Version="0.10.21" />
<PackageReference Include="Dove.FFmpeg.Windows" Version="1.0.0" />
<ProjectReference Include="..\..\src\FFmpegView.Bass\FFmpegView.Bass.csproj" />
<ProjectReference Include="..\..\src\FFmpegView.Avalonia\FFmpegView.Avalonia.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="Styles\Icons.xaml">
<Generator>MSBuild:Compile</Generator>
</None>
</ItemGroup>
</Project>
83 changes: 81 additions & 2 deletions samples/FFmpegView.AvaloniaDemo/MainWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,87 @@
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:vm="using:FFmpegView.AvaloniaDemo.Models"
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="250"
x:Class="FFmpegView.AvaloniaDemo.MainWindow"
Title="FFmpegView.AvaloniaDemo">
<FFmpegView x:Name="playerView" />
xmlns:player="clr-namespace:FFmpegView;assembly=FFmpegView.Avalonia"
Title="FFmpegView.AvaloniaDemo"
ShowInTaskbar="True"
WindowState="Normal"
ExtendClientAreaToDecorationsHint="True"
Background="#0E1621">

<Design.DataContext>
<vm:MainWindowViewModel/>
</Design.DataContext>

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="35"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Panel Grid.Row="0">
<Button Name="openFileBtn"
Click="OnOpenFileClick"
Margin="10, 10, 10, 0" Background="#17212B"
IsEnabled="{Binding IsPlayEnabled}">
<PathIcon Data="{StaticResource folder_open}" />
</Button>
</Panel>
<Border Grid.Row="1" Margin="10" BorderBrush="#17212B" BorderThickness="1" CornerRadius="3">
<Grid Name="Player">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="0"/>
<RowDefinition Height="55"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>

<player:FFmpegView x:Name="Media" />
<StackPanel Grid.Row="2" Orientation="Vertical" Background="#17212B" ZIndex="1">
<Panel>
<Slider Name="PositionSlider" Cursor="Hand" Height="45" IsVisible="True"
IsEnabled="{Binding SeekBarVisible}"
IsSnapToTickEnabled="False"
Minimum="{Binding PlaybackStartTime}"
Maximum="{Binding PlaybackEndTime}"
Value="{Binding Position, Mode=TwoWay}">
</Slider>
</Panel>
<StackPanel IsVisible="True" Orientation="Horizontal" Margin="10">
<TextBlock Text="{Binding Position, StringFormat={}{0:0000.0}}}" Width="40" FontSize="11"></TextBlock>
<TextBlock Text="/" Margin="0, 0, 3, 0" FontSize="11"></TextBlock>
<TextBlock Text="{Binding PlaybackEndTime, StringFormat={}{0:0000.0}}}}" Width="40" FontSize="11"></TextBlock>
</StackPanel>
</StackPanel>

<Grid Grid.Row="3" Background="#17212B" ZIndex="0">
<DockPanel HorizontalAlignment="Center" VerticalAlignment="Top">

<DockPanel Width="160">
<Button Name="playBtn"
Click="OnPlayClick"
Margin="0, 0, 10, 0" Background="#17212B"
IsEnabled="{Binding IsPlayEnabled}">
<PathIcon Data="{StaticResource PlayIcon}" />
</Button>
<Button Name="pauseBtn" Click="OnPauseClick" Background="#17212B" Margin="0, 0, 10, 0">
<PathIcon Data="{StaticResource PauseIcon}" />
</Button>
<Button Name="stopBtn" Click="OnStopClick" Background="#17212B">
<PathIcon Data="{StaticResource StopIcon}" />
</Button>
</DockPanel>
</DockPanel>
</Grid>

</Grid>
</Border>
</Grid>
</AeroWindow>
90 changes: 83 additions & 7 deletions samples/FFmpegView.AvaloniaDemo/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,103 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using FFmpegView.Avalonia;
using FFmpegView.Bass;
using System.Collections.Generic;
using System;
using System.IO;

namespace FFmpegView.AvaloniaDemo
{
public class MainWindow : Window
public partial class MainWindow : Window
{
private FFmpegView Media;
private string source;

public MainWindow()
{
AvaloniaXamlLoader.Load(this);
InitializeComponent();
DataContext = App.ViewModel;

var media = this.FindControl<FFmpegView>("Media");
media.SetAudioHandler(new BassAudioStreamDecoder());
media.PositionChanged += OnMediaPositionChanged;
}

private void InitializeComponent()
{
Width = 800;
Height = 600;
}

private void OnMediaPositionChanged(object sender, PositionChangedEventArgs e)
{
var media = sender as FFmpegView;

if (!media.IsOpen)
{
return;
}

if (media.State == MediaState.IsSeeking)
return;

App.ViewModel.PositionTime = media.Position;
App.ViewModel.Position = media.Position?.TotalSeconds;

App.ViewModel.PlaybackStartTime = media.PlaybackStartTime?.TotalSeconds ?? 0;
App.ViewModel.PlaybackEndTime = media.PlaybackEndTime?.TotalSeconds ?? 0;
}

private void OnPlayClick(object? sender, RoutedEventArgs e)
{
if (Design.IsDesignMode)
return;


App.ViewModel?.MediaElement?.Play();
}

private async void OnPauseClick(object sender, RoutedEventArgs e)
{
if (Design.IsDesignMode)
return;

App.ViewModel?.MediaElement?.Pause();
}

private void OnStopClick(object sender, RoutedEventArgs e)
{
if (Design.IsDesignMode)
return;

App.ViewModel.MediaElement.Position = TimeSpan.Zero;
}

private async void OnOpenFileClick(object? sender, RoutedEventArgs e)
{
if (Design.IsDesignMode)
return;

OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.AllowMultiple = false;

var result = await openFileDialog.ShowAsync(this);

if (result != null)
{
foreach (string filePath in result)
{
if (File.Exists(filePath))
{
source = filePath;

var playerView = this.FindControl<FFmpegView>("playerView");
var audioStreamDecoder = new BassAudioStreamDecoder();
audioStreamDecoder.Headers = new Dictionary<string, string> { { "User-Agent", "ffmpeg_demo" } };
playerView.SetAudioHandler(audioStreamDecoder);
playerView.Play("http://vfx.mtime.cn/Video/2019/02/04/mp4/190204084208765161.mp4");
App.ViewModel?.MediaElement?.Play(filePath);
System.Threading.Thread.Sleep(10);
App.ViewModel?.MediaElement?.Pause();
}
}
}
}
}
}
89 changes: 89 additions & 0 deletions samples/FFmpegView.AvaloniaDemo/Models/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using Avalonia.Controls;
using FFmpegView.Bass;
using System;
using System.Collections.Generic;
using System.Text;

namespace FFmpegView.AvaloniaDemo.Models
{
public class MainWindowViewModel: ViewModelBase
{
private FFmpegView mediaElement;
private double? position = 0;
private double positionStep = 0;
private TimeSpan? positionTime = TimeSpan.Zero;
private double playbackStartTime = 0.05;
private double playbackEndTime = 0.1;
private bool seekBarVisible = false;

public FFmpegView? MediaElement
{
get
{
if (mediaElement == null)
{
FFmpegView? media = App.MainWindow.FindControl<FFmpegView>("Media");
mediaElement = media;
}

return mediaElement;
}
}

public TimeSpan? PositionTime
{
get => positionTime;
set
{
positionTime = value;
NotifyPropertyChanged(nameof(PositionTime));
}
}

public double? Position
{
get => position;
set
{
position = value;
NotifyPropertyChanged(nameof(Position));
}
}

public double PositionStep
{
get => positionStep;
set
{
positionStep = value;
NotifyPropertyChanged(nameof(PositionStep));
}
}

public double PlaybackStartTime
{
get => playbackStartTime;
set
{
playbackStartTime = value;
NotifyPropertyChanged(nameof(PlaybackStartTime));
}
}

public double PlaybackEndTime
{
get => playbackEndTime;
set
{
playbackEndTime = value;
NotifyPropertyChanged(nameof(PlaybackEndTime));
}
}

public bool SeekBarVisible
{
get => seekBarVisible;
set => SetProperty(ref seekBarVisible, value);
}
}
}
Loading