...
 
Commits (18)
using System;
using VLC.Model;
using VLC.Universal.Views.UserControls.Shell;
using VLC.Utils;
namespace VLC.Commands.MediaLibrary
{
public class OpenConvertDialogCommand : AlwaysExecutableCommand
{
public override async void Execute(object parameter)
{
if (parameter is IMediaItem)
{
var media = parameter as IMediaItem;
var dialog = new TranscodingDialog
{
Media = media
};
await dialog.ShowAsync();
}
}
}
}
\ No newline at end of file
......@@ -520,6 +520,24 @@ namespace VLC.Model.Library
}
}
// Clean roaming
foreach (var tmpCopyRoaming in await ApplicationData.Current.RoamingFolder.GetFilesAsync())
{
try
{
if (tmpCopyRoaming?.Name.Contains("VLC-transcoded") == true)
{
await tmpCopyRoaming.DeleteAsync(StorageDeleteOption.PermanentDelete);
}
}
catch (Exception ex)
{
LogHelper.Log("failed to cleanup roaming transcoded file copy " + tmpCopyRoaming?.Name);
LogHelper.Log(ex.Message);
LogHelper.Log(ex.StackTrace);
}
}
// Clean tracks
var tracks = LoadTracks();
foreach (var track in tracks)
......
......@@ -189,6 +189,7 @@ namespace VLC.Utils
public static string Back => _resourcesLoader.GetString(nameof(Back));
public static string Add => _resourcesLoader.GetString(nameof(Add));
public static string CopyToLocalStorage => _resourcesLoader.GetString(nameof(CopyToLocalStorage));
public static string Convert => _resourcesLoader.GetString(nameof(Convert));
// PLAY ..
public static string Play => _resourcesLoader.GetString(nameof(Play));
......
......@@ -18,6 +18,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Commands\MediaLibrary\CopyToLocalStorageCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Commands\MediaLibrary\DeleteFromLibraryCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Commands\MediaLibrary\IndexMediaLibraryCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Commands\MediaLibrary\OpenConvertDialogCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Commands\MediaPlayback\ChangeAudioDelayCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Commands\MediaPlayback\ChangePlaybackSpeedRateCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Commands\MediaPlayback\ChangeSpuDelayCommand.cs" />
......
......@@ -8,20 +8,13 @@
**********************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel.Resources.Core;
using Windows.System;
using Windows.UI.Xaml;
using VLC.Database;
using VLC.Helpers;
using VLC.Helpers.MusicLibrary;
using VLC.Model.Music;
using VLC.Model.Video;
using VLC.Model;
using VLC.UI.Views.MusicPages;
using Windows.Storage;
using Windows.UI;
using Windows.UI.Core;
......@@ -29,10 +22,6 @@ using VLC.Commands.Navigation;
using VLC.Commands.Settings;
using VLC.Utils;
using Windows.UI.Xaml.Navigation;
using Autofac;
using VLC.Services.RunTime;
using Windows.UI.ViewManagement;
using Windows.Foundation.Metadata;
namespace VLC.ViewModels.Settings
{
......@@ -745,5 +734,14 @@ namespace VLC.ViewModels.Settings
Locator.MainVM.Panels.Remove(settingsPanel);
}
#endregion
public List<string> Profiles { get; } = new List<string>
{
"VP9",
"720p",
"1080p"
};
public string VLCTranscoded => "-VLC-transcoded-";
}
}
}
\ No newline at end of file
......@@ -101,6 +101,7 @@ namespace VLC.ViewModels.VideoVM
public static TVShowClickedCommand TVShowClickedCommand { get; private set; } = new TVShowClickedCommand();
public PlayVideoCommand OpenVideo { get; private set; } = new PlayVideoCommand();
public RestartAndPlayCommand RestartAndPlayCommand { get; } = new RestartAndPlayCommand();
public OpenConvertDialogCommand OpenConvertDialogCommand { get; } = new OpenConvertDialogCommand();
public CloseFlyoutAndPlayVideoCommand CloseFlyoutAndPlayVideoCommand { get; private set; } = new CloseFlyoutAndPlayVideoCommand();
public DeleteFromLibraryCommand DeleteFromLibraryCommand { get; private set; } = new DeleteFromLibraryCommand();
public ChangeVideoViewCommand ChangeVideoViewCommand { get; private set; } = new ChangeVideoViewCommand();
......
......@@ -275,6 +275,9 @@
<Compile Include="Views\UserControls\Shell\DesktopHomePageController.xaml.cs">
<DependentUpon>DesktopHomePageController.xaml</DependentUpon>
</Compile>
<Compile Include="Views\UserControls\Shell\TranscodingDialog.xaml.cs">
<DependentUpon>TranscodingDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Views\UserControls\Shell\VLCDialog.xaml.cs">
<DependentUpon>VLCDialog.xaml</DependentUpon>
</Compile>
......@@ -869,6 +872,33 @@
<Content Include="..\..\libvlc\Universal\vlc-$(TargetedSDKArchitecture)\$(Configuration)\plugins\misc\libxml_plugin.dll">
<Link>plugins\misc\libxml_plugin.dll</Link>
</Content>
<Content Include="..\..\libvlc\Universal\vlc-$(TargetedSDKArchitecture)\$(Configuration)\plugins\mux\libmux_asf_plugin.dll" Condition="$(Platform) != 'ARM'">
<Link>plugins\mux\libmux_asf_plugin.dll</Link>
</Content>
<Content Include="..\..\libvlc\Universal\vlc-$(TargetedSDKArchitecture)\$(Configuration)\plugins\mux\libmux_avi_plugin.dll" Condition="$(Platform) != 'ARM'">
<Link>plugins\mux\libmux_avi_plugin.dll</Link>
</Content>
<Content Include="..\..\libvlc\Universal\vlc-$(TargetedSDKArchitecture)\$(Configuration)\plugins\mux\libmux_dummy_plugin.dll" Condition="$(Platform) != 'ARM'">
<Link>plugins\mux\libmux_dummy_plugin.dll</Link>
</Content>
<Content Include="..\..\libvlc\Universal\vlc-$(TargetedSDKArchitecture)\$(Configuration)\plugins\mux\libmux_mp4_plugin.dll" Condition="$(Platform) != 'ARM'">
<Link>plugins\mux\libmux_mp4_plugin.dll</Link>
</Content>
<Content Include="..\..\libvlc\Universal\vlc-$(TargetedSDKArchitecture)\$(Configuration)\plugins\mux\libmux_mpjpeg_plugin.dll" Condition="$(Platform) != 'ARM'">
<Link>plugins\mux\libmux_mpjpeg_plugin.dll</Link>
</Content>
<Content Include="..\..\libvlc\Universal\vlc-$(TargetedSDKArchitecture)\$(Configuration)\plugins\mux\libmux_ogg_plugin.dll" Condition="$(Platform) != 'ARM'">
<Link>plugins\mux\libmux_ogg_plugin.dll</Link>
</Content>
<Content Include="..\..\libvlc\Universal\vlc-$(TargetedSDKArchitecture)\$(Configuration)\plugins\mux\libmux_ps_plugin.dll" Condition="$(Platform) != 'ARM'">
<Link>plugins\mux\libmux_ps_plugin.dll</Link>
</Content>
<Content Include="..\..\libvlc\Universal\vlc-$(TargetedSDKArchitecture)\$(Configuration)\plugins\mux\libmux_ts_plugin.dll" Condition="$(Platform) != 'ARM'">
<Link>plugins\mux\libmux_ts_plugin.dll</Link>
</Content>
<Content Include="..\..\libvlc\Universal\vlc-$(TargetedSDKArchitecture)\$(Configuration)\plugins\mux\libmux_wav_plugin.dll" Condition="$(Platform) != 'ARM'">
<Link>plugins\mux\libmux_wav_plugin.dll</Link>
</Content>
<Content Include="..\..\libvlc\Universal\vlc-$(TargetedSDKArchitecture)\$(Configuration)\plugins\packetizer\libpacketizer_a52_plugin.dll">
<Link>plugins\packetizer\libpacketizer_a52_plugin.dll</Link>
</Content>
......@@ -1537,6 +1567,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\UserControls\Shell\TranscodingDialog.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\UserControls\Shell\VLCDialog.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
......
......@@ -88,20 +88,32 @@
</AppBarButton.Icon>
</AppBarButton>
</Grid>
<AppBarButton Grid.Row="2"
Name="RestartPlayback"
Label="{Binding Source={StaticResource Strings}, Path=Restart}"
Click="ActionButton_Click"
Margin="{StaticResource FrameMarginBottomLeft}"
Command="{Binding Source={StaticResource Locator}, Path=VideoLibraryVM.RestartAndPlayCommand}"
CommandParameter="{Binding}"
Visibility="{Binding TimeWatchedSeconds, Converter={StaticResource NegatedCountToVisibilityConverter}}"
Style="{StaticResource AppBarButtonStyleHorizontal}">
<AppBarButton.Icon>
<FontIcon Glyph="&#xE777;"
FontFamily="Segoe MDL2 Assets" />
</AppBarButton.Icon>
</AppBarButton>
<Grid Grid.Row="2"
Margin="{StaticResource FrameMarginVertical}">
<AppBarButton Name="RestartPlayback"
Label="{Binding Source={StaticResource Strings}, Path=Restart}"
Click="ActionButton_Click"
Margin="{StaticResource FrameMarginLeft}"
Command="{Binding Source={StaticResource Locator}, Path=VideoLibraryVM.RestartAndPlayCommand}"
CommandParameter="{Binding}"
Visibility="{Binding TimeWatchedSeconds, Converter={StaticResource NegatedCountToVisibilityConverter}}"
Style="{StaticResource AppBarButtonStyleHorizontal}">
<AppBarButton.Icon>
<FontIcon Glyph="&#xE777;"
FontFamily="Segoe MDL2 Assets" />
</AppBarButton.Icon>
</AppBarButton>
<AppBarButton Name="Convert"
Label="Convert"
Click="ActionButton_Click"
Margin="{StaticResource FrameMarginRight}"
Visibility="{Binding Source={StaticResource Locator}, Path=SettingsVM.DesktopMode}"
Command="{Binding Source={StaticResource Locator}, Path=VideoLibraryVM.OpenConvertDialogCommand}"
CommandParameter="{Binding}"
Style="{StaticResource AppBarButtonStyleHorizontal}"
HorizontalAlignment="Right">
</AppBarButton>
</Grid>
<TextBlock Grid.Row="3"
Margin="{StaticResource FrameMarginLeft}"
Style="{StaticResource BodyTextBlockStyle}">
......
......@@ -26,6 +26,8 @@ namespace VLC.UI.Views.UserControls.Flyouts
var RootGrid = sender as Border;
RootGrid.MaxWidth = 400;
RootGrid.MaxHeight = 400;
if (RestartPlayback.Visibility == Visibility.Collapsed)
Convert.HorizontalAlignment = HorizontalAlignment.Left;
}
}
}
<ContentDialog
x:Class="VLC.Universal.Views.UserControls.Shell.TranscodingDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:VLC.Universal.Views.UserControls.Shell"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:userControls="using:VLC.UI.Views.UserControls"
mc:Ignorable="d"
Title="Convert"
PrimaryButtonText="Start"
SecondaryButtonText="{Binding Source={StaticResource Strings}, Path=Cancel}"
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
SecondaryButtonClick="ContentDialog_SecondaryButtonClick">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<ComboBox Name="Profiles"
Margin="0,12"
ItemsSource="{Binding Source={StaticResource Locator}, Path=SettingsVM.Profiles}"
SelectedIndex="1"
Style="{StaticResource VLCLightComboBox}"
Width="160">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Row="1">
<Run Text="You will find your transcoded file in your Videos folder"/>
</TextBlock>
<ProgressRing Name="ProgressRing"
Visibility="Collapsed"
Grid.Row="1"
IsActive="True"
Style="{StaticResource LoadingRing}"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
<TextBlock Name="Progress" Grid.Row="2" Visibility="Collapsed" HorizontalAlignment="Center"/>
<TextBlock Text="%" Grid.Row="2" Visibility="Collapsed" HorizontalAlignment="Center"/>
</Grid>
</ContentDialog>
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using libVLCX;
using VLC.Helpers;
using VLC.Model;
using VLC.Utils;
using VLC.ViewModels;
namespace VLC.Universal.Views.UserControls.Shell
{
public sealed partial class TranscodingDialog : ContentDialog
{
MediaPlayer _mediaPlayer;
Instance _instance;
string _currentTranscodedFileName;
string _transcodedFilePathRoaming;
string _selectedProfile;
const string Mkv = ".mkv";
const string Webm = ".webm";
string Extension => _selectedProfile == "VP9" ? Webm : Mkv;
string TranscodingMaxWidth => _selectedProfile == "720p" ? "1280" : "1920";
string TranscodingMaxHeight => _selectedProfile == "720p" ? "720" : "1080";
public IMediaItem Media { get; set; }
public TranscodingDialog()
{
InitializeComponent();
}
// needs to be accessed from UI thread
string TranscodedFileName => Media.Name + Locator.SettingsVM.VLCTranscoded + Profiles.SelectedItem + Extension;
string GetTranscodedFilePathAsync()
{
var roamingFolderPath = ApplicationData.Current.RoamingFolder.Path;
_currentTranscodedFileName = TranscodedFileName;
return Path.Combine(roamingFolderPath, _currentTranscodedFileName);
}
async void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
args.Cancel = true;
_selectedProfile = Profiles.SelectedItem as string;
var options = new List<string>{"-vv"};
_instance = new Instance(options);
Media.VlcMedia = new Media(_instance, Media.Path, FromType.FromPath);
_transcodedFilePathRoaming = GetTranscodedFilePathAsync();
var transcodeOption = GetTranscodeOptionString(_transcodedFilePathRoaming, _selectedProfile);
if (string.IsNullOrEmpty(transcodeOption)) //abort
{
LogHelper.Log("could not setup transcode options with path " + _transcodedFilePathRoaming + " and selectedProfile " + _selectedProfile);
return;
}
Media.VlcMedia.addOption(transcodeOption);
_mediaPlayer = new MediaPlayer(Media.VlcMedia);
_mediaPlayer.eventManager().OnPositionChanged += OnOnPositionChanged;
_mediaPlayer.eventManager().OnEndReached += OnOnEndReached;
_mediaPlayer.eventManager().OnEncounteredError += OnOnEncounteredError;
_mediaPlayer.play();
await DispatchHelper.InvokeInUIThread(CoreDispatcherPriority.Normal, () =>
{
ProgressRing.Visibility = Visibility.Visible;
Progress.Visibility = Visibility.Visible;
IsPrimaryButtonEnabled = false;
});
}
async void OnOnEncounteredError()
{
LogHelper.Log($"error while transcoding file dst {_transcodedFilePathRoaming}");
await DispatchHelper.InvokeInUIThread(CoreDispatcherPriority.Normal, () =>
{
ProgressRing.Visibility = Visibility.Collapsed;
});
await CleanupAndHide();
}
async void OnOnPositionChanged(float transcodingProgress)
{
var progress = (int)(transcodingProgress * 100) + "%";
await DispatchHelper.InvokeInUIThread(CoreDispatcherPriority.Normal, () =>
{
Progress.Text = progress;
});
}
async void OnOnEndReached()
{
var videoLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Videos);
var file = await StorageFile.GetFileFromPathAsync(_transcodedFilePathRoaming);
// copy transcoded file from sandbox to video fodler
await file.CopyAsync(videoLibrary.SaveFolder, _currentTranscodedFileName, NameCollisionOption.GenerateUniqueName);
await CleanupAndHide();
}
string GetTranscodeOptionString(string transcodedFilePath, string selectedProfile)
{
if (string.IsNullOrEmpty(selectedProfile) || string.IsNullOrEmpty(selectedProfile)) return string.Empty;
switch (selectedProfile)
{
case "VP9":
return
":sout=#transcode{vcodec=VP90,vb=2000,acodec=vorb}" +
":std{access=file,mux=avformat{mux=webm},dst='" + transcodedFilePath + "'}'";
case "720p":
return
":sout=#transcode{venc=qsv{rc-method=vbr,bitrate-max=40000000,gop-size=24,target-usage=speed}," +
"vcodec=h264,acodec=mp4a,maxwidth=" + TranscodingMaxWidth + ",maxheight=" + TranscodingMaxHeight + "}" +
":std{access=file,mux=mkv,dst='" + transcodedFilePath + "'}'";
case "1080p":
return
":sout=#transcode{venc=qsv{rc-method=vbr,bitrate-max=40000000,gop-size=24,target-usage=speed}," +
"vcodec=h264,acodec=mp4a,maxwidth=" + TranscodingMaxWidth + ",maxheight=" + TranscodingMaxHeight + "}" +
":std{access=file,mux=mkv,dst='" + transcodedFilePath + "'}'";
default:
return string.Empty;
}
}
async void ContentDialog_SecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
if (_mediaPlayer == null)
{
Hide();
return;
}
await CleanupAndHide();
}
async Task CleanupAndHide()
{
if (_mediaPlayer == null)
{
Hide();
return;
}
if (_mediaPlayer.isPlaying())
_mediaPlayer.stop();
await DispatchHelper.InvokeInUIThread(CoreDispatcherPriority.Normal, () =>
{
ProgressRing.IsActive = false;
ProgressRing.Visibility = Visibility.Collapsed;
});
_mediaPlayer.eventManager().OnPositionChanged -= OnOnPositionChanged;
_mediaPlayer.eventManager().OnEndReached -= OnOnEndReached;
_mediaPlayer.eventManager().OnEncounteredError -= OnOnEncounteredError;
Media.VlcMedia = null;
_mediaPlayer = null;
_instance = null;
await DispatchHelper.InvokeInUIThread(CoreDispatcherPriority.Normal, Hide);
}
}
}
\ No newline at end of file
......@@ -46,6 +46,22 @@ namespace libVLCX
delete [] c_argv;
}
Instance::Instance(Windows::Foundation::Collections::IVector<Platform::String^>^ argv)
{
int extraArgs = 2;
auto c_argv = new char*[argv->Size + extraArgs];
unsigned int i = 0;
for (auto arg : argv)
{
c_argv[i++] = _strdup((const char*) VLCString(arg));
}
m_instance = VLC::Instance(i, c_argv);
for (unsigned j = 0; j < i; ++j)
free(c_argv[j]);
delete [] c_argv;
}
void Instance::Trim()
{
m_dxManager->Trim();
......
......@@ -160,6 +160,8 @@ namespace libVLCX
*/
Instance(Windows::Foundation::Collections::IVector<Platform::String^>^ argv, SwapChainPanel^ panel);
Instance(Windows::Foundation::Collections::IVector<Platform::String^>^ argv);
/**
* Try to start a user interface for the libvlc instance.
*
......