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:
Jon Thysell
2021-04-08 10:37:35 -07:00
committed by GitHub
parent 3dc607c461
commit d7ac23d39b
52 changed files with 2675 additions and 1329 deletions

View File

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

View File

@@ -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" />

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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