React Native Windows updates (#2206)
Various updates for React Native Windows **Docs** * Fixed windows installation in readme * Added local dev setup instructions **Build** * Added VS solutions for RNW 0.61, 0.62, and 0.63+ * Added clang-formatting definition **Features** * Fixed autolinking for RNW 0.63+ * Added support for `rate` property **Examples** * Upgraded examples/basic to RN 0.61 and replaced broken windows app
This commit is contained in:
@@ -1,22 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<CppWinRTOptimized>true</CppWinRTOptimized>
|
||||
<CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
|
||||
<MinimalCoreWin>true</MinimalCoreWin>
|
||||
<ProjectGuid>{765365e4-9553-4900-9f69-e26d4309c8da}</ProjectGuid>
|
||||
<ProjectGuid>{0d1e54d3-4be1-4daf-98bf-124c28c85014}</ProjectGuid>
|
||||
<ProjectName>ReactNativeVideoCPP</ProjectName>
|
||||
<RootNamespace>ReactNativeVideoCPP</RootNamespace>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||
<MinimumVisualStudioVersion>16.0</MinimumVisualStudioVersion>
|
||||
<AppContainerApplication>true</AppContainerApplication>
|
||||
<ApplicationType>Windows Store</ApplicationType>
|
||||
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
|
||||
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.18362.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.15063.0</WindowsTargetPlatformMinVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.16299.0</WindowsTargetPlatformMinVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="ReactNativeWindowsProps">
|
||||
<ReactNativeWindowsDir Condition="'$(ReactNativeWindowsDir)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(SolutionDir), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\</ReactNativeWindowsDir>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
<Configuration>Debug</Configuration>
|
||||
@@ -53,9 +56,6 @@
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
</PropertyGroup>
|
||||
@@ -71,15 +71,15 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
<Import Project="..\..\..\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems" Label="Shared" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="PropertySheet.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="ReactNativeWindowsPropertySheets">
|
||||
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.props" Condition="Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.props')" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup>
|
||||
@@ -104,6 +104,7 @@
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
|
||||
@@ -145,22 +146,26 @@
|
||||
<ItemGroup>
|
||||
<None Include="PropertySheet.props" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\react-native-windows\Microsoft.ReactNative\Microsoft.ReactNative.vcxproj">
|
||||
<Project>{f7d32bd0-2749-483e-9a0d-1635ef7e3136}</Project>
|
||||
<Private>false</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ReactNativeWindowsTargets">
|
||||
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.targets" Condition="Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureReactNativeWindowsTargets" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references targets in your node_modules\react-native-windows folder. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.props')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.props'))" />
|
||||
<Error Condition="!Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.targets'))" />
|
||||
</Target>
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
<Import Project="$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.190730.2\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
<Error Condition="!Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)packages\Microsoft.Windows.CppWinRT.2.0.200316.3\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
</Target>
|
||||
<Target Name="Deploy" />
|
||||
</Project>
|
||||
|
@@ -29,9 +29,6 @@
|
||||
<ItemGroup>
|
||||
<None Include="PropertySheet.props" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="readme.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="ReactPackageProvider.idl" />
|
||||
<Midl Include="ReactVideoView.idl" />
|
||||
|
@@ -1,7 +1,9 @@
|
||||
namespace ReactNativeVideoCPP {
|
||||
[webhosthidden]
|
||||
[default_interface]
|
||||
runtimeclass ReactPackageProvider : Microsoft.ReactNative.IReactPackageProvider {
|
||||
ReactPackageProvider();
|
||||
};
|
||||
} // namespace ReactNativeVideoCPP
|
||||
namespace ReactNativeVideoCPP
|
||||
{
|
||||
[webhosthidden]
|
||||
[default_interface]
|
||||
runtimeclass ReactPackageProvider : Microsoft.ReactNative.IReactPackageProvider
|
||||
{
|
||||
ReactPackageProvider();
|
||||
};
|
||||
}
|
||||
|
@@ -16,229 +16,233 @@ using namespace Windows::Media::Playback;
|
||||
|
||||
namespace winrt::ReactNativeVideoCPP::implementation {
|
||||
|
||||
ReactVideoView::ReactVideoView(winrt::Microsoft::ReactNative::IReactContext const& reactContext)
|
||||
: m_reactContext(reactContext){
|
||||
// always create and set the player here instead of depending on auto-create logic
|
||||
// in the MediaPlayerElement (only when auto play is on or URI is set)
|
||||
m_player = winrt::Windows::Media::Playback::MediaPlayer();
|
||||
SetMediaPlayer(m_player);
|
||||
m_uiDispatcher = CoreWindow::GetForCurrentThread().Dispatcher();
|
||||
ReactVideoView::ReactVideoView(winrt::Microsoft::ReactNative::IReactContext const &reactContext)
|
||||
: m_reactContext(reactContext) {
|
||||
// always create and set the player here instead of depending on auto-create logic
|
||||
// in the MediaPlayerElement (only when auto play is on or URI is set)
|
||||
m_player = winrt::Windows::Media::Playback::MediaPlayer();
|
||||
SetMediaPlayer(m_player);
|
||||
m_uiDispatcher = CoreWindow::GetForCurrentThread().Dispatcher();
|
||||
|
||||
m_mediaOpenedToken = m_player.MediaOpened(winrt::auto_revoke, [ref = get_weak()](auto const& sender, auto const& args) {
|
||||
m_mediaOpenedToken =
|
||||
m_player.MediaOpened(winrt::auto_revoke, [ref = get_weak()](auto const &sender, auto const &args) {
|
||||
if (auto self = ref.get()) {
|
||||
self->OnMediaOpened(sender, args);
|
||||
self->OnMediaOpened(sender, args);
|
||||
}
|
||||
});
|
||||
m_mediaFailedToken = m_player.MediaFailed(winrt::auto_revoke, [ref = get_weak()](auto const& sender, auto const& args) {
|
||||
});
|
||||
m_mediaFailedToken =
|
||||
m_player.MediaFailed(winrt::auto_revoke, [ref = get_weak()](auto const &sender, auto const &args) {
|
||||
if (auto self = ref.get()) {
|
||||
self->OnMediaFailed(sender, args);
|
||||
self->OnMediaFailed(sender, args);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
m_mediaEndedToken = m_player.MediaEnded(winrt::auto_revoke, [ref = get_weak()](auto const& sender, auto const& args) {
|
||||
if (auto self = ref.get()) {
|
||||
self->OnMediaEnded(sender, args);
|
||||
}
|
||||
});
|
||||
m_mediaEndedToken = m_player.MediaEnded(winrt::auto_revoke, [ref = get_weak()](auto const &sender, auto const &args) {
|
||||
if (auto self = ref.get()) {
|
||||
self->OnMediaEnded(sender, args);
|
||||
}
|
||||
});
|
||||
|
||||
m_bufferingStartedToken =
|
||||
m_player.PlaybackSession().BufferingStarted(winrt::auto_revoke, [ref = get_weak()](auto const& sender, auto const& args) {
|
||||
m_bufferingStartedToken = m_player.PlaybackSession().BufferingStarted(
|
||||
winrt::auto_revoke, [ref = get_weak()](auto const &sender, auto const &args) {
|
||||
if (auto self = ref.get()) {
|
||||
self->OnBufferingStarted(sender, args);
|
||||
self->OnBufferingStarted(sender, args);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
m_bufferingEndedToken =
|
||||
m_player.PlaybackSession().BufferingEnded(winrt::auto_revoke, [ref = get_weak()](auto const& sender, auto const& args) {
|
||||
m_bufferingEndedToken = m_player.PlaybackSession().BufferingEnded(
|
||||
winrt::auto_revoke, [ref = get_weak()](auto const &sender, auto const &args) {
|
||||
if (auto self = ref.get()) {
|
||||
self->OnBufferingEnded(sender, args);
|
||||
self->OnBufferingEnded(sender, args);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
m_seekCompletedToken =
|
||||
m_player.PlaybackSession().SeekCompleted(winrt::auto_revoke, [ref = get_weak()](auto const& sender, auto const& args) {
|
||||
m_seekCompletedToken = m_player.PlaybackSession().SeekCompleted(
|
||||
winrt::auto_revoke, [ref = get_weak()](auto const &sender, auto const &args) {
|
||||
if (auto self = ref.get()) {
|
||||
self->OnSeekCompleted(sender, args);
|
||||
self->OnSeekCompleted(sender, args);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
m_timer = Windows::UI::Xaml::DispatcherTimer();
|
||||
m_timer.Interval(std::chrono::milliseconds{ 250 });
|
||||
m_timer.Start();
|
||||
auto token = m_timer.Tick([ref = get_weak()](auto const&, auto const&) {
|
||||
if (auto self = ref.get()){
|
||||
if (auto mediaPlayer = self->m_player) {
|
||||
if (mediaPlayer.PlaybackSession().PlaybackState() ==
|
||||
winrt::Windows::Media::Playback::MediaPlaybackState::Playing) {
|
||||
auto currentTimeInSeconds = mediaPlayer.PlaybackSession().Position().count() / 10000000;
|
||||
self->m_reactContext.DispatchEvent(
|
||||
*self,
|
||||
L"topProgress",
|
||||
[&](winrt::Microsoft::ReactNative::IJSValueWriter const& eventDataWriter) noexcept {
|
||||
eventDataWriter.WriteObjectBegin();
|
||||
{
|
||||
WriteProperty(eventDataWriter, L"currentTime", currentTimeInSeconds);
|
||||
WriteProperty(eventDataWriter, L"playableDuration", 0.0);
|
||||
}
|
||||
eventDataWriter.WriteObjectEnd();
|
||||
});
|
||||
m_timer = Windows::UI::Xaml::DispatcherTimer();
|
||||
m_timer.Interval(std::chrono::milliseconds{250});
|
||||
m_timer.Start();
|
||||
auto token = m_timer.Tick([ref = get_weak()](auto const &, auto const &) {
|
||||
if (auto self = ref.get()) {
|
||||
if (auto mediaPlayer = self->m_player) {
|
||||
if (mediaPlayer.PlaybackSession().PlaybackState() ==
|
||||
winrt::Windows::Media::Playback::MediaPlaybackState::Playing) {
|
||||
auto currentTimeInSeconds = mediaPlayer.PlaybackSession().Position().count() / 10000000;
|
||||
self->m_reactContext.DispatchEvent(
|
||||
*self,
|
||||
L"topProgress",
|
||||
[&](winrt::Microsoft::ReactNative::IJSValueWriter const &eventDataWriter) noexcept {
|
||||
eventDataWriter.WriteObjectBegin();
|
||||
{
|
||||
WriteProperty(eventDataWriter, L"currentTime", currentTimeInSeconds);
|
||||
WriteProperty(eventDataWriter, L"playableDuration", 0.0);
|
||||
}
|
||||
}
|
||||
eventDataWriter.WriteObjectEnd();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ReactVideoView::OnMediaOpened(IInspectable const&, IInspectable const&) {
|
||||
runOnQueue([weak_this{ get_weak() }]() {
|
||||
if (auto strong_this{ weak_this.get() }) {
|
||||
if (auto mediaPlayer = strong_this->m_player) {
|
||||
auto width = mediaPlayer.PlaybackSession().NaturalVideoWidth();
|
||||
auto height = mediaPlayer.PlaybackSession().NaturalVideoHeight();
|
||||
auto orientation = (width > height) ? L"landscape" : L"portrait";
|
||||
auto durationInSeconds = mediaPlayer.PlaybackSession().NaturalDuration().count() / 10000000;
|
||||
auto currentTimeInSeconds = mediaPlayer.PlaybackSession().Position().count() / 10000000;
|
||||
void ReactVideoView::OnMediaOpened(IInspectable const &, IInspectable const &) {
|
||||
runOnQueue([weak_this{get_weak()}]() {
|
||||
if (auto strong_this{weak_this.get()}) {
|
||||
if (auto mediaPlayer = strong_this->m_player) {
|
||||
auto width = mediaPlayer.PlaybackSession().NaturalVideoWidth();
|
||||
auto height = mediaPlayer.PlaybackSession().NaturalVideoHeight();
|
||||
auto orientation = (width > height) ? L"landscape" : L"portrait";
|
||||
auto durationInSeconds = mediaPlayer.PlaybackSession().NaturalDuration().count() / 10000000;
|
||||
auto currentTimeInSeconds = mediaPlayer.PlaybackSession().Position().count() / 10000000;
|
||||
|
||||
strong_this->m_reactContext.DispatchEvent(
|
||||
*strong_this,
|
||||
L"topLoad",
|
||||
[&](winrt::Microsoft::ReactNative::IJSValueWriter const& eventDataWriter) noexcept {
|
||||
eventDataWriter.WriteObjectBegin();
|
||||
{
|
||||
WriteProperty(eventDataWriter, L"duration", durationInSeconds);
|
||||
WriteProperty(eventDataWriter, L"currentTime", currentTimeInSeconds);
|
||||
strong_this->m_reactContext.DispatchEvent(
|
||||
*strong_this,
|
||||
L"topLoad",
|
||||
[&](winrt::Microsoft::ReactNative::IJSValueWriter const &eventDataWriter) noexcept {
|
||||
eventDataWriter.WriteObjectBegin();
|
||||
{
|
||||
WriteProperty(eventDataWriter, L"duration", durationInSeconds);
|
||||
WriteProperty(eventDataWriter, L"currentTime", currentTimeInSeconds);
|
||||
|
||||
eventDataWriter.WritePropertyName(L"naturalSize");
|
||||
{
|
||||
eventDataWriter.WriteObjectBegin();
|
||||
WriteProperty(eventDataWriter, L"width", width);
|
||||
WriteProperty(eventDataWriter, L"height", height);
|
||||
WriteProperty(eventDataWriter, L"orientation", orientation);
|
||||
WriteProperty(eventDataWriter, L"orientation", orientation);
|
||||
eventDataWriter.WriteObjectEnd();
|
||||
}
|
||||
eventDataWriter.WritePropertyName(L"naturalSize");
|
||||
{
|
||||
eventDataWriter.WriteObjectBegin();
|
||||
WriteProperty(eventDataWriter, L"width", width);
|
||||
WriteProperty(eventDataWriter, L"height", height);
|
||||
WriteProperty(eventDataWriter, L"orientation", orientation);
|
||||
WriteProperty(eventDataWriter, L"orientation", orientation);
|
||||
eventDataWriter.WriteObjectEnd();
|
||||
}
|
||||
|
||||
WriteProperty(eventDataWriter, L"canPlayFastForward", false);
|
||||
WriteProperty(eventDataWriter, L"canPlaySlowForward", false);
|
||||
WriteProperty(eventDataWriter, L"canPlaySlow", false);
|
||||
WriteProperty(eventDataWriter, L"canStepBackward", false);
|
||||
WriteProperty(eventDataWriter, L"canStepForward", false);
|
||||
}
|
||||
eventDataWriter.WriteObjectEnd();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
WriteProperty(eventDataWriter, L"canPlayFastForward", false);
|
||||
WriteProperty(eventDataWriter, L"canPlaySlowForward", false);
|
||||
WriteProperty(eventDataWriter, L"canPlaySlow", false);
|
||||
WriteProperty(eventDataWriter, L"canStepBackward", false);
|
||||
WriteProperty(eventDataWriter, L"canStepForward", false);
|
||||
}
|
||||
eventDataWriter.WriteObjectEnd();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ReactVideoView::OnMediaFailed(IInspectable const&, IInspectable const&) {}
|
||||
void ReactVideoView::OnMediaFailed(IInspectable const &, IInspectable const &) {}
|
||||
|
||||
void ReactVideoView::OnMediaEnded(IInspectable const&, IInspectable const&) {
|
||||
runOnQueue([weak_this{ get_weak() }]() {
|
||||
if (auto strong_this{ weak_this.get() }) {
|
||||
strong_this->m_reactContext.DispatchEvent(*strong_this, L"topEnd", nullptr);
|
||||
}
|
||||
});
|
||||
void ReactVideoView::OnMediaEnded(IInspectable const &, IInspectable const &) {
|
||||
runOnQueue([weak_this{get_weak()}]() {
|
||||
if (auto strong_this{weak_this.get()}) {
|
||||
strong_this->m_reactContext.DispatchEvent(*strong_this, L"topEnd", nullptr);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ReactVideoView::OnBufferingStarted(IInspectable const&, IInspectable const&) {}
|
||||
void ReactVideoView::OnBufferingStarted(IInspectable const &, IInspectable const &) {}
|
||||
|
||||
void ReactVideoView::OnBufferingEnded(IInspectable const&, IInspectable const&) {}
|
||||
void ReactVideoView::OnBufferingEnded(IInspectable const &, IInspectable const &) {}
|
||||
|
||||
void ReactVideoView::OnSeekCompleted(IInspectable const&, IInspectable const&) {
|
||||
runOnQueue([weak_this{ get_weak() }]() {
|
||||
if (auto strong_this{ weak_this.get() }) {
|
||||
strong_this->m_reactContext.DispatchEvent(*strong_this, L"topSeek", nullptr);
|
||||
}
|
||||
});
|
||||
void ReactVideoView::OnSeekCompleted(IInspectable const &, IInspectable const &) {
|
||||
runOnQueue([weak_this{get_weak()}]() {
|
||||
if (auto strong_this{weak_this.get()}) {
|
||||
strong_this->m_reactContext.DispatchEvent(*strong_this, L"topSeek", nullptr);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ReactVideoView::Set_ProgressUpdateInterval(int64_t interval) {
|
||||
m_timer.Interval(std::chrono::milliseconds{ interval });
|
||||
m_timer.Interval(std::chrono::milliseconds{interval});
|
||||
}
|
||||
|
||||
void ReactVideoView::Set_IsLoopingEnabled(bool value) {
|
||||
m_isLoopingEnabled = value;
|
||||
if (m_player != nullptr) {
|
||||
m_player.IsLoopingEnabled(m_isLoopingEnabled);
|
||||
}
|
||||
m_isLoopingEnabled = value;
|
||||
if (m_player != nullptr) {
|
||||
m_player.IsLoopingEnabled(m_isLoopingEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
void ReactVideoView::Set_UriString(hstring const& value) {
|
||||
m_uriString = value;
|
||||
if (m_player != nullptr) {
|
||||
auto uri = Uri(m_uriString);
|
||||
m_player.Source(MediaSource::CreateFromUri(uri));
|
||||
}
|
||||
void ReactVideoView::Set_UriString(hstring const &value) {
|
||||
m_uriString = value;
|
||||
if (m_player != nullptr) {
|
||||
auto uri = Uri(m_uriString);
|
||||
m_player.Source(MediaSource::CreateFromUri(uri));
|
||||
}
|
||||
}
|
||||
|
||||
void ReactVideoView::Set_Paused(bool value) {
|
||||
m_isPaused = value;
|
||||
if (m_player != nullptr) {
|
||||
if (m_isPaused) {
|
||||
if (IsPlaying(m_player.PlaybackSession().PlaybackState())) {
|
||||
m_player.Pause();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!IsPlaying(m_player.PlaybackSession().PlaybackState())) {
|
||||
m_player.Play();
|
||||
}
|
||||
}
|
||||
m_isPaused = value;
|
||||
if (m_player != nullptr) {
|
||||
if (m_isPaused) {
|
||||
if (IsPlaying(m_player.PlaybackSession().PlaybackState())) {
|
||||
m_player.Pause();
|
||||
}
|
||||
} else {
|
||||
if (!IsPlaying(m_player.PlaybackSession().PlaybackState())) {
|
||||
m_player.Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReactVideoView::Set_AutoPlay(bool autoPlay) {
|
||||
m_player.AutoPlay(autoPlay);
|
||||
m_player.AutoPlay(autoPlay);
|
||||
}
|
||||
|
||||
void ReactVideoView::Set_Muted(bool isMuted) {
|
||||
m_isMuted = isMuted;
|
||||
if (m_player != nullptr) {
|
||||
m_player.IsMuted(m_isMuted);
|
||||
}
|
||||
m_isMuted = isMuted;
|
||||
if (m_player != nullptr) {
|
||||
m_player.IsMuted(m_isMuted);
|
||||
}
|
||||
}
|
||||
|
||||
void ReactVideoView::Set_Controls(bool useControls) {
|
||||
m_useControls = useControls;
|
||||
AreTransportControlsEnabled(m_useControls);
|
||||
m_useControls = useControls;
|
||||
AreTransportControlsEnabled(m_useControls);
|
||||
}
|
||||
|
||||
void ReactVideoView::Set_FullScreen(bool fullScreen) {
|
||||
m_fullScreen = fullScreen;
|
||||
IsFullWindow(m_fullScreen);
|
||||
m_fullScreen = fullScreen;
|
||||
IsFullWindow(m_fullScreen);
|
||||
|
||||
if (m_fullScreen)
|
||||
{
|
||||
Set_Controls(true); // full window will always have transport control enabled
|
||||
}
|
||||
if (m_fullScreen) {
|
||||
Set_Controls(true); // full window will always have transport control enabled
|
||||
}
|
||||
}
|
||||
|
||||
void ReactVideoView::Set_Volume(double volume) {
|
||||
m_volume = volume;
|
||||
if (m_player != nullptr) {
|
||||
m_player.Volume(m_volume);
|
||||
}
|
||||
m_volume = volume;
|
||||
if (m_player != nullptr) {
|
||||
m_player.Volume(m_volume);
|
||||
}
|
||||
}
|
||||
|
||||
void ReactVideoView::Set_Position(double position) {
|
||||
m_position = position;
|
||||
if (m_player != nullptr) {
|
||||
std::chrono::seconds duration(static_cast<int>(m_position));
|
||||
m_player.PlaybackSession().Position(duration);
|
||||
}
|
||||
m_position = position;
|
||||
if (m_player != nullptr) {
|
||||
std::chrono::seconds duration(static_cast<int>(m_position));
|
||||
m_player.PlaybackSession().Position(duration);
|
||||
}
|
||||
}
|
||||
|
||||
void ReactVideoView::Set_PlaybackRate(double rate) {
|
||||
if (m_player != nullptr) {
|
||||
m_player.PlaybackSession().PlaybackRate(rate);
|
||||
}
|
||||
}
|
||||
|
||||
bool ReactVideoView::IsPlaying(MediaPlaybackState currentState) {
|
||||
return (
|
||||
currentState == MediaPlaybackState::Buffering ||
|
||||
currentState == MediaPlaybackState::Opening ||
|
||||
currentState == MediaPlaybackState::Playing
|
||||
);
|
||||
return (
|
||||
currentState == MediaPlaybackState::Buffering || currentState == MediaPlaybackState::Opening ||
|
||||
currentState == MediaPlaybackState::Playing);
|
||||
}
|
||||
|
||||
void ReactVideoView::runOnQueue(std::function<void()>&& func) {
|
||||
m_uiDispatcher.RunAsync(
|
||||
winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, [func = std::move(func)]() { func(); });
|
||||
void ReactVideoView::runOnQueue(std::function<void()> &&func) {
|
||||
m_uiDispatcher.RunAsync(
|
||||
winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, [func = std::move(func)]() { func(); });
|
||||
}
|
||||
|
||||
} // namespace winrt::ReactNativeVideoCPP::implementation
|
||||
|
@@ -18,6 +18,7 @@ struct ReactVideoView : ReactVideoViewT<ReactVideoView> {
|
||||
void Set_FullScreen(bool fullScreen);
|
||||
void Set_ProgressUpdateInterval(int64_t interval);
|
||||
void Set_AutoPlay(bool autoPlay);
|
||||
void Set_PlaybackRate(double rate);
|
||||
|
||||
private:
|
||||
hstring m_uriString;
|
||||
|
@@ -1,16 +1,20 @@
|
||||
namespace ReactNativeVideoCPP {
|
||||
|
||||
[default_interface] runtimeclass ReactVideoView : Windows.UI.Xaml.Controls.MediaPlayerElement {
|
||||
ReactVideoView(Microsoft.ReactNative.IReactContext context);
|
||||
void Set_UriString(String uri);
|
||||
void Set_IsLoopingEnabled(Boolean isLoopingEnabled);
|
||||
void Set_Paused(Boolean isPaused);
|
||||
void Set_Muted(Boolean isMuted);
|
||||
void Set_Volume(Double volume);
|
||||
void Set_Position(Double position);
|
||||
void Set_Controls(Boolean useControls);
|
||||
void Set_FullScreen(Boolean fullScreen);
|
||||
void Set_ProgressUpdateInterval(Int64 interval);
|
||||
void Set_AutoPlay(Boolean autoPlay);
|
||||
};
|
||||
} // namespace ReactNativeVideoCPP
|
||||
namespace ReactNativeVideoCPP
|
||||
{
|
||||
[webhosthidden]
|
||||
[default_interface]
|
||||
runtimeclass ReactVideoView : Windows.UI.Xaml.Controls.MediaPlayerElement
|
||||
{
|
||||
ReactVideoView(Microsoft.ReactNative.IReactContext context);
|
||||
void Set_UriString(String uri);
|
||||
void Set_IsLoopingEnabled(Boolean isLoopingEnabled);
|
||||
void Set_Paused(Boolean isPaused);
|
||||
void Set_Muted(Boolean isMuted);
|
||||
void Set_Volume(Double volume);
|
||||
void Set_Position(Double position);
|
||||
void Set_Controls(Boolean useControls);
|
||||
void Set_FullScreen(Boolean fullScreen);
|
||||
void Set_ProgressUpdateInterval(Int64 interval);
|
||||
void Set_AutoPlay(Boolean autoPlay);
|
||||
void Set_PlaybackRate(Double rate);
|
||||
};
|
||||
}
|
||||
|
@@ -49,6 +49,7 @@ IMapView<hstring, ViewManagerPropertyType> ReactVideoViewManager::NativeProps()
|
||||
nativeProps.Insert(L"controls", ViewManagerPropertyType::Boolean);
|
||||
nativeProps.Insert(L"fullscreen", ViewManagerPropertyType::Boolean);
|
||||
nativeProps.Insert(L"progressUpdateInterval", ViewManagerPropertyType::Number);
|
||||
nativeProps.Insert(L"rate", ViewManagerPropertyType::Number);
|
||||
|
||||
return nativeProps.GetView();
|
||||
}
|
||||
@@ -64,28 +65,30 @@ void ReactVideoViewManager::UpdateProperties(
|
||||
auto const &propertyValue = pair.second;
|
||||
if (!propertyValue.IsNull()) {
|
||||
if (propertyName == "src") {
|
||||
auto const &srcMap = propertyValue.AsObject();
|
||||
auto const &uri = srcMap.at("uri");
|
||||
reactVideoView.Set_UriString(to_hstring(uri.AsString()));
|
||||
auto const &srcMap = propertyValue.AsObject();
|
||||
auto const &uri = srcMap.at("uri");
|
||||
reactVideoView.Set_UriString(to_hstring(uri.AsString()));
|
||||
} else if (propertyName == "resizeMode") {
|
||||
reactVideoView.Stretch(static_cast<Stretch>(std::stoul(propertyValue.AsString())));
|
||||
reactVideoView.Stretch(static_cast<Stretch>(std::stoul(propertyValue.AsString())));
|
||||
} else if (propertyName == "repeat") {
|
||||
reactVideoView.Set_IsLoopingEnabled(propertyValue.AsBoolean());
|
||||
reactVideoView.Set_IsLoopingEnabled(propertyValue.AsBoolean());
|
||||
} else if (propertyName == "paused") {
|
||||
m_paused = propertyValue.AsBoolean();
|
||||
reactVideoView.Set_Paused(m_paused);
|
||||
m_paused = propertyValue.AsBoolean();
|
||||
reactVideoView.Set_Paused(m_paused);
|
||||
} else if (propertyName == "muted") {
|
||||
reactVideoView.Set_Muted(propertyValue.AsBoolean());
|
||||
reactVideoView.Set_Muted(propertyValue.AsBoolean());
|
||||
} else if (propertyName == "volume") {
|
||||
reactVideoView.Set_Volume(propertyValue.AsDouble());
|
||||
reactVideoView.Set_Volume(propertyValue.AsDouble());
|
||||
} else if (propertyName == "seek") {
|
||||
reactVideoView.Set_Position(propertyValue.AsDouble());
|
||||
reactVideoView.Set_Position(propertyValue.AsDouble());
|
||||
} else if (propertyName == "controls") {
|
||||
reactVideoView.Set_Controls(propertyValue.AsBoolean());
|
||||
reactVideoView.Set_Controls(propertyValue.AsBoolean());
|
||||
} else if (propertyName == "fullscreen") {
|
||||
reactVideoView.Set_FullScreen(propertyValue.AsBoolean());
|
||||
reactVideoView.Set_FullScreen(propertyValue.AsBoolean());
|
||||
} else if (propertyName == "progressUpdateInterval") {
|
||||
reactVideoView.Set_ProgressUpdateInterval(propertyValue.AsInt64());
|
||||
reactVideoView.Set_ProgressUpdateInterval(propertyValue.AsInt64());
|
||||
} else if (propertyName == "rate") {
|
||||
reactVideoView.Set_PlaybackRate(propertyValue.AsDouble());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.190730.2" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.200316.3" targetFramework="native" />
|
||||
</packages>
|
@@ -11,10 +11,10 @@
|
||||
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
|
||||
#include <winrt/Windows.UI.Xaml.Controls.h>
|
||||
#include <winrt/Windows.UI.Xaml.Data.h>
|
||||
#include <winrt/Windows.UI.Xaml.Input.h>
|
||||
#include <winrt/Windows.UI.Xaml.Interop.h>
|
||||
#include <winrt/Windows.UI.Xaml.Markup.h>
|
||||
#include <winrt/Windows.UI.Xaml.Navigation.h>
|
||||
#include <winrt/Windows.UI.Xaml.h>
|
||||
#include <winrt/Windows.UI.Xaml.Input.h>
|
||||
|
||||
#include <winrt/Microsoft.ReactNative.h>
|
||||
|
Reference in New Issue
Block a user