From a4fec8eb99dad0457f968ba5dc37f2842a8eb9c3 Mon Sep 17 00:00:00 2001 From: Di Da Date: Tue, 25 Feb 2020 06:21:06 -0800 Subject: [PATCH] Add support for react-native Windows Cpp/WinRT (#1893) This also deprecates the old react-native windows implementation --- README.md | 44 +-- .../Properties/AssemblyInfo.cs | 36 -- .../ReactNativeVideo.Net46.csproj | 74 ---- .../ReactVideoEventType.cs | 15 - .../ReactVideoEventTypeExtensions.cs | 36 -- .../ReactVideoPackage.cs | 30 -- .../ReactNativeVideo.Net46/ReactVideoView.cs | 359 ----------------- .../ReactVideoViewManager.cs | 139 ------- .../ReactNativeVideo.Net46/packages.config | 4 - windows/ReactNativeVideo.sln | 49 --- .../Properties/AssemblyInfo.cs | 29 -- .../Properties/ReactNativeVideo.rd.xml | 33 -- .../ReactNativeVideo/ReactNativeVideo.csproj | 116 ------ .../ReactNativeVideo/ReactVideoEventType.cs | 15 - .../ReactVideoEventTypeExtensions.cs | 36 -- windows/ReactNativeVideo/ReactVideoPackage.cs | 30 -- windows/ReactNativeVideo/ReactVideoView.cs | 365 ------------------ .../ReactNativeVideo/ReactVideoViewManager.cs | 137 ------- windows/ReactNativeVideo/project.json | 17 - .../ReactNativeVideoCPP/PropertySheet.props | 16 + .../ReactNativeVideoCPP.def | 3 + .../ReactNativeVideoCPP.vcxproj | 157 ++++++++ .../ReactNativeVideoCPP.vcxproj.filters | 39 ++ .../ReactPackageProvider.cpp | 17 + .../ReactPackageProvider.h | 20 + .../ReactPackageProvider.idl | 7 + .../ReactNativeVideoCPP/ReactVideoView.cpp | 244 ++++++++++++ windows/ReactNativeVideoCPP/ReactVideoView.h | 56 +++ .../ReactNativeVideoCPP/ReactVideoView.idl | 16 + .../ReactVideoViewManager.cpp | 110 ++++++ .../ReactVideoViewManager.h | 55 +++ windows/ReactNativeVideoCPP/packages.config | 4 + windows/ReactNativeVideoCPP/pch.cpp | 1 + windows/ReactNativeVideoCPP/pch.h | 20 + 34 files changed, 778 insertions(+), 1551 deletions(-) delete mode 100644 windows/ReactNativeVideo.Net46/Properties/AssemblyInfo.cs delete mode 100644 windows/ReactNativeVideo.Net46/ReactNativeVideo.Net46.csproj delete mode 100644 windows/ReactNativeVideo.Net46/ReactVideoEventType.cs delete mode 100644 windows/ReactNativeVideo.Net46/ReactVideoEventTypeExtensions.cs delete mode 100644 windows/ReactNativeVideo.Net46/ReactVideoPackage.cs delete mode 100644 windows/ReactNativeVideo.Net46/ReactVideoView.cs delete mode 100644 windows/ReactNativeVideo.Net46/ReactVideoViewManager.cs delete mode 100644 windows/ReactNativeVideo.Net46/packages.config delete mode 100644 windows/ReactNativeVideo.sln delete mode 100644 windows/ReactNativeVideo/Properties/AssemblyInfo.cs delete mode 100644 windows/ReactNativeVideo/Properties/ReactNativeVideo.rd.xml delete mode 100644 windows/ReactNativeVideo/ReactNativeVideo.csproj delete mode 100644 windows/ReactNativeVideo/ReactVideoEventType.cs delete mode 100644 windows/ReactNativeVideo/ReactVideoEventTypeExtensions.cs delete mode 100644 windows/ReactNativeVideo/ReactVideoPackage.cs delete mode 100644 windows/ReactNativeVideo/ReactVideoView.cs delete mode 100644 windows/ReactNativeVideo/ReactVideoViewManager.cs delete mode 100644 windows/ReactNativeVideo/project.json create mode 100644 windows/ReactNativeVideoCPP/PropertySheet.props create mode 100644 windows/ReactNativeVideoCPP/ReactNativeVideoCPP.def create mode 100644 windows/ReactNativeVideoCPP/ReactNativeVideoCPP.vcxproj create mode 100644 windows/ReactNativeVideoCPP/ReactNativeVideoCPP.vcxproj.filters create mode 100644 windows/ReactNativeVideoCPP/ReactPackageProvider.cpp create mode 100644 windows/ReactNativeVideoCPP/ReactPackageProvider.h create mode 100644 windows/ReactNativeVideoCPP/ReactPackageProvider.idl create mode 100644 windows/ReactNativeVideoCPP/ReactVideoView.cpp create mode 100644 windows/ReactNativeVideoCPP/ReactVideoView.h create mode 100644 windows/ReactNativeVideoCPP/ReactVideoView.idl create mode 100644 windows/ReactNativeVideoCPP/ReactVideoViewManager.cpp create mode 100644 windows/ReactNativeVideoCPP/ReactVideoViewManager.h create mode 100644 windows/ReactNativeVideoCPP/packages.config create mode 100644 windows/ReactNativeVideoCPP/pch.cpp create mode 100644 windows/ReactNativeVideoCPP/pch.h diff --git a/README.md b/README.md index 9210d3f4..ea518143 100644 --- a/README.md +++ b/README.md @@ -184,52 +184,34 @@ protected List getPackages() { ### Windows installation
- Windows details + Windows RNW C++/WinRT details Make the following additions to the given files manually: #### **windows/myapp.sln** -Add the `ReactNativeVideo` project to your solution. +Add the `ReactNativeVideoCPP` project to your solution. -1. Open the solution in Visual Studio 2015 +1. Open the solution in Visual Studio 2019 2. Right-click Solution icon in Solution Explorer > Add > Existing Project - * UWP: Select `node_modules\react-native-video\windows\ReactNativeVideo\ReactNativeVideo.csproj` - * WPF: Select `node_modules\react-native-video\windows\ReactNativeVideo.Net46\ReactNativeVideo.Net46.csproj` + Select `node_modules\react-native-video\windows\ReactNativeVideoCPP\ReactNativeVideoCPP.vcxproj` -#### **windows/myapp/myapp.csproj** +#### **windows/myapp/myapp.vcxproj** -Add a reference to `ReactNativeVideo` to your main application project. From Visual Studio 2015: +Add a reference to `ReactNativeVideoCPP` to your main application project. From Visual Studio 2019: 1. Right-click main application project > Add > Reference... - * UWP: Check `ReactNativeVideo` from Solution Projects. - * WPF: Check `ReactNativeVideo.Net46` from Solution Projects. + Check `ReactNativeVideoCPP` from Solution Projects. -#### **MainPage.cs** +2. Modify files below to add the video package providers to your main application project +#### **pch.h** -Add the `ReactVideoPackage` class to your list of exported packages. -```cs -using ReactNative; -using ReactNative.Modules.Core; -using ReactNative.Shell; -using ReactNativeVideo; // <-- Add this -using System.Collections.Generic; -... +Add `#include "winrt/ReactNativeVideoCPP.h"`. - public override List Packages - { - get - { - return new List - { - new MainReactPackage(), - new ReactVideoPackage(), // <-- Add this - }; - } - } +#### **app.cpp** + +Add `PackageProviders().Append(winrt::ReactNativeVideoCPP::ReactPackageProvider());` before `InitializeComponent();`. -... -```
### react-native-dom installation diff --git a/windows/ReactNativeVideo.Net46/Properties/AssemblyInfo.cs b/windows/ReactNativeVideo.Net46/Properties/AssemblyInfo.cs deleted file mode 100644 index ca102d8a..00000000 --- a/windows/ReactNativeVideo.Net46/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ReactNativeVideo.Net46")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ReactNativeVideo.Net46")] -[assembly: AssemblyCopyright("Copyright © 2016")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("2d8406ab-0674-42d3-8fe3-41d251403df8")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/windows/ReactNativeVideo.Net46/ReactNativeVideo.Net46.csproj b/windows/ReactNativeVideo.Net46/ReactNativeVideo.Net46.csproj deleted file mode 100644 index e59ab904..00000000 --- a/windows/ReactNativeVideo.Net46/ReactNativeVideo.Net46.csproj +++ /dev/null @@ -1,74 +0,0 @@ - - - - - Debug - AnyCPU - {2D8406AB-0674-42D3-8FE3-41D251403DF8} - Library - Properties - ReactNativeVideo.Net46 - ReactNativeVideo.Net46 - v4.6 - 512 - - - x64 - bin\x64\Debug\ - - - x64 - bin\x64\Release\ - - - x86 - bin\x86\Debug\ - - - x86 - bin\x86\Release\ - - - - $(SolutionDir)\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll - True - - - - - - - - - - - - - - - - - - - - - - - - - - {22CBFF9C-FE36-43E8-A246-266C7635E662} - ReactNative.Net46 - - - - - - - diff --git a/windows/ReactNativeVideo.Net46/ReactVideoEventType.cs b/windows/ReactNativeVideo.Net46/ReactVideoEventType.cs deleted file mode 100644 index dd3f3feb..00000000 --- a/windows/ReactNativeVideo.Net46/ReactVideoEventType.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace ReactNativeVideo -{ - enum ReactVideoEventType - { - LoadStart, - Load, - Error, - Progress, - Seek, - End, - Stalled, - Resume, - ReadyForDisplay, - } -} diff --git a/windows/ReactNativeVideo.Net46/ReactVideoEventTypeExtensions.cs b/windows/ReactNativeVideo.Net46/ReactVideoEventTypeExtensions.cs deleted file mode 100644 index 5f2b63db..00000000 --- a/windows/ReactNativeVideo.Net46/ReactVideoEventTypeExtensions.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using static System.FormattableString; - -namespace ReactNativeVideo -{ - static class ReactVideoEventTypeExtensions - { - public static string GetEventName(this ReactVideoEventType eventType) - { - switch (eventType) - { - case ReactVideoEventType.LoadStart: - return "onVideoLoadStart"; - case ReactVideoEventType.Load: - return "onVideoLoad"; - case ReactVideoEventType.Error: - return "onVideoError"; - case ReactVideoEventType.Progress: - return "onVideoProgress"; - case ReactVideoEventType.Seek: - return "onVideoSeek"; - case ReactVideoEventType.End: - return "onVideoEnd"; - case ReactVideoEventType.Stalled: - return "onPlaybackStalled"; - case ReactVideoEventType.Resume: - return "onPlaybackResume"; - case ReactVideoEventType.ReadyForDisplay: - return "onReadyForDisplay"; - default: - throw new NotSupportedException( - Invariant($"No event name added for event type '{eventType}'.")); - } - } - } -} diff --git a/windows/ReactNativeVideo.Net46/ReactVideoPackage.cs b/windows/ReactNativeVideo.Net46/ReactVideoPackage.cs deleted file mode 100644 index b8cc654b..00000000 --- a/windows/ReactNativeVideo.Net46/ReactVideoPackage.cs +++ /dev/null @@ -1,30 +0,0 @@ -using ReactNative.Bridge; -using ReactNative.Modules.Core; -using ReactNative.UIManager; -using System; -using System.Collections.Generic; - -namespace ReactNativeVideo -{ - public class ReactVideoPackage : IReactPackage - { - public IReadOnlyList CreateJavaScriptModulesConfig() - { - return Array.Empty(); - } - - public IReadOnlyList CreateNativeModules(ReactContext reactContext) - { - return Array.Empty(); - - } - - public IReadOnlyList CreateViewManagers(ReactContext reactContext) - { - return new List - { - new ReactVideoViewManager(), - }; - } - } -} diff --git a/windows/ReactNativeVideo.Net46/ReactVideoView.cs b/windows/ReactNativeVideo.Net46/ReactVideoView.cs deleted file mode 100644 index 643965ee..00000000 --- a/windows/ReactNativeVideo.Net46/ReactVideoView.cs +++ /dev/null @@ -1,359 +0,0 @@ -using Newtonsoft.Json.Linq; -using ReactNative.Bridge; -using ReactNative.UIManager; -using ReactNative.UIManager.Events; -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using System.Windows.Media.Animation; -using System.Windows.Threading; - -namespace ReactNativeVideo -{ - class ReactVideoView : Border, IDisposable - { - public const string EVENT_PROP_SEEK_TIME = "seekTime"; - - private readonly DispatcherTimer _timer; - - private bool _isLoopingEnabled; - private bool _isPaused; - private bool _isMuted; - private bool _isCompleted; - private double _volume; - private double _rate; - - private MediaPlayer _player; - private VideoDrawing _drawing; - private MediaTimeline _timeline; - private MediaClock _clock; - private DrawingBrush _brush; - - public ReactVideoView() - { - _timer = new DispatcherTimer(); - _timer.Interval = TimeSpan.FromMilliseconds(250.0); - _timer.Start(); - _player = new MediaPlayer(); - _drawing = new VideoDrawing(); - _drawing.Rect = new Rect(0, 0, 100, 100); // Set the initial viewing area - _drawing.Player = _player; - _brush = new DrawingBrush(_drawing); - this.Background = _brush; - } - - public string Source - { - set - { - var uri = new Uri(value); - - _player.Open(uri); - - this.GetReactContext() - .GetNativeModule() - .EventDispatcher - .DispatchEvent( - new ReactVideoEvent( - ReactVideoEventType.LoadStart.GetEventName(), - this.GetTag(), - new JObject - { - {"src", uri} - })); - - ApplyModifiers(); - SubscribeEvents(); - } - } - - public bool IsLoopingEnabled - { - set - { - _isLoopingEnabled = value; - } - } - - public bool IsMuted - { - set - { - _isMuted = value; - if (_player != null) - { - _player.IsMuted = _isMuted; - } - } - } - - public bool IsPaused - { - set - { - _isPaused = value; - if (_player != null) - { - if (_isPaused) - { - _player.Pause(); - } - else - { - _player.Play(); - } - } - } - } - - public double Volume - { - set - { - _volume = value; - if (_player != null) - { - _player.Volume = _volume; - } - } - } - - public double Rate - { - set - { - _rate = value; - if (_player != null) - { - _player.SpeedRatio = _rate; - } - } - } - - public double ProgressUpdateInterval - { - set - { - _timer.Interval = TimeSpan.FromSeconds(value); - } - } - - public void Seek(double seek) - { - if (_player != null) - { - _player.Position = TimeSpan.FromSeconds(seek); - } - } - - public void Dispose() - { - if (_player != null) - { - _timer.Tick -= OnTick; - _player.MediaOpened -= OnMediaOpened; - _player.MediaFailed -= OnMediaFailed; - _player.MediaEnded -= OnMediaEnded; - _player.BufferingStarted -= OnBufferingStarted; - _player.BufferingEnded -= OnBufferingEnded; - // _player.SeekCompleted -= OnSeekCompleted; - } - - _timer.Stop(); - } - - private void ApplyModifiers() - { - IsLoopingEnabled = _isLoopingEnabled; - IsMuted = _isMuted; - IsPaused = _isPaused; - Volume = _volume; - Rate = _rate; - } - - private void SubscribeEvents() - { - _timer.Tick += OnTick; - _player.MediaOpened += OnMediaOpened; - _player.MediaFailed += OnMediaFailed; - _player.MediaEnded += OnMediaEnded; - _player.BufferingStarted += OnBufferingStarted; - _player.BufferingEnded += OnBufferingEnded; - //_player.SeekCompleted += OnSeekCompleted; - } - - private void OnTick(object sender, object e) - { - if (_player != null && !_isCompleted && !_isPaused) - { - this.GetReactContext() - .GetNativeModule() - .EventDispatcher - .DispatchEvent( - new ReactVideoEvent( - ReactVideoEventType.Progress.GetEventName(), - this.GetTag(), - new JObject - { - { "currentTime", _player.Position.TotalSeconds }, - { "playableDuration", 0.0 /* TODO */ } - })); - } - } - - private void OnMediaOpened(object sender, EventArgs args) - { - RunOnDispatcher(delegate - { - var width = _player.NaturalVideoWidth; - var height = _player.NaturalVideoHeight; - var orientation = (width > height) ? "landscape" : "portrait"; - var size = new JObject - { - { "width", width }, - { "height", height }, - { "orientation", orientation } - }; - - _drawing.Rect = new Rect(new Size(width, height)); - - this.GetReactContext() - .GetNativeModule() - .EventDispatcher - .DispatchEvent( - new ReactVideoEvent( - ReactVideoEventType.Load.GetEventName(), - this.GetTag(), - new JObject - { - { "duration", _player.NaturalDuration.TimeSpan.TotalSeconds }, - { "currentTime", _player.Position.TotalSeconds }, - { "naturalSize", size }, - { "canPlayFastForward", false }, - { "canPlaySlowForward", false }, - { "canPlaySlow", false }, - { "canPlayReverse", false }, - { "canStepBackward", false }, - { "canStepForward", false } - })); - }); - } - - private void OnMediaFailed(object sender, ExceptionEventArgs args) - { - var errorData = new JObject - { - { "what", args.ErrorException.HResult.ToString() }, - { "extra", args.ErrorException.Message } - }; - - this.GetReactContext() - .GetNativeModule() - .EventDispatcher - .DispatchEvent( - new ReactVideoEvent( - ReactVideoEventType.Error.GetEventName(), - this.GetTag(), - new JObject - { - { "error", errorData } - })); - } - - private void OnMediaEnded(object sender, EventArgs args) - { - if (_isLoopingEnabled) - { - _player.Position = TimeSpan.Zero; - _player.Play(); - } - else - { - _isCompleted = true; - this.GetReactContext() - .GetNativeModule() - .EventDispatcher - .DispatchEvent( - new ReactVideoEvent( - ReactVideoEventType.End.GetEventName(), - this.GetTag(), - null)); - } - } - - private void OnBufferingStarted(object sender, EventArgs args) - { - this.GetReactContext() - .GetNativeModule() - .EventDispatcher - .DispatchEvent( - new ReactVideoEvent( - ReactVideoEventType.Stalled.GetEventName(), - this.GetTag(), - new JObject())); - } - - private void OnBufferingEnded(object sender, EventArgs args) - { - this.GetReactContext() - .GetNativeModule() - .EventDispatcher - .DispatchEvent( - new ReactVideoEvent( - ReactVideoEventType.Resume.GetEventName(), - this.GetTag(), - new JObject())); - } - - private void OnSeekCompleted(object sender, EventArgs args) - { - this.GetReactContext() - .GetNativeModule() - .EventDispatcher.DispatchEvent( - new ReactVideoEvent( - ReactVideoEventType.Seek.GetEventName(), - this.GetTag(), - new JObject())); - } - - private static async void RunOnDispatcher(Action action) - { - await Application.Current.Dispatcher.InvokeAsync(action).Task.ConfigureAwait(false); - } - - class ReactVideoEvent : Event - { - private readonly string _eventName; - private readonly JObject _eventData; - - public ReactVideoEvent(string eventName, int viewTag, JObject eventData) - : base(viewTag) - { - _eventName = eventName; - _eventData = eventData; - } - - public override string EventName - { - get - { - return _eventName; - } - } - - public override bool CanCoalesce - { - get - { - return false; - } - } - - public override void Dispatch(RCTEventEmitter eventEmitter) - { - eventEmitter.receiveEvent(ViewTag, EventName, _eventData); - } - } - } -} diff --git a/windows/ReactNativeVideo.Net46/ReactVideoViewManager.cs b/windows/ReactNativeVideo.Net46/ReactVideoViewManager.cs deleted file mode 100644 index e71f22c1..00000000 --- a/windows/ReactNativeVideo.Net46/ReactVideoViewManager.cs +++ /dev/null @@ -1,139 +0,0 @@ -using Newtonsoft.Json.Linq; -using ReactNative.UIManager; -using ReactNative.UIManager.Annotations; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Windows; -using System.Windows.Media; - -namespace ReactNativeVideo -{ - class ReactVideoViewManager : SimpleViewManager - { - public override string Name - { - get - { - return "RCTVideo"; - } - } - - public override IReadOnlyDictionary ExportedViewConstants - { - get - { - return new Dictionary - { - { "ScaleNone", ((int)Stretch.None).ToString() }, - { "ScaleToFill", ((int)Stretch.UniformToFill).ToString() }, - { "ScaleAspectFit", ((int)Stretch.Uniform).ToString() }, - { "ScaleAspectFill", ((int)Stretch.Fill).ToString() }, - }; - } - } - - public override IReadOnlyDictionary ExportedCustomDirectEventTypeConstants - { - get - { - var events = new Dictionary(); - var eventTypes = Enum.GetValues(typeof(ReactVideoEventType)).OfType(); - foreach (var eventType in eventTypes) - { - events.Add(eventType.GetEventName(), new Dictionary - { - { "registrationName", eventType.GetEventName() }, - }); - } - - return events; - } - } - - [ReactProp("src")] - public void SetSource(ReactVideoView view, JObject source) - { - view.Source = source.Value("uri"); - } - - [ReactProp("resizeMode")] - public void SetResizeMode(ReactVideoView view, string resizeMode) - { - throw new NotImplementedException("Resize Mode has not been implemented for WPF."); - // view.Stretch = (Stretch)int.Parse(resizeMode); - } - - [ReactProp("repeat")] - public void SetRepeat(ReactVideoView view, bool repeat) - { - view.IsLoopingEnabled = repeat; - } - - [ReactProp("paused")] - public void SetPaused(ReactVideoView view, bool paused) - { - view.IsPaused = paused; - } - - [ReactProp("muted")] - public void SetMuted(ReactVideoView view, bool muted) - { - view.IsMuted = muted; - } - - [ReactProp("volume", DefaultDouble = 1.0)] - public void SetVolume(ReactVideoView view, double volume) - { - view.Volume = volume; - } - - [ReactProp("seek")] - public void SetSeek(ReactVideoView view, double? seek) - { - if (seek.HasValue) - { - view.Seek(seek.Value); - } - } - - [ReactProp("rate", DefaultDouble = 1.0)] - public void SetPlaybackRate(ReactVideoView view, double rate) - { - view.Rate = rate; - } - - [ReactProp("playInBackground")] - public void SetPlayInBackground(ReactVideoView view, bool playInBackground) - { - throw new NotImplementedException("Play in background has not been implemented on Windows."); - } - - // TODO: Utilize MediaElement when user control enabled and MediaPlayer + VideoDrawing when disabled - [ReactProp("controls")] - public void SetControls(ReactVideoView view, bool controls) - { - throw new NotImplementedException("User controls have not been implemented on WPF."); - } - - [ReactProp("progressUpdateInterval")] - public void SetProgressUpdateInterval(ReactVideoView view, double progressUpdateInterval) - { - view.ProgressUpdateInterval = progressUpdateInterval; - } - - public override void OnDropViewInstance(ThemedReactContext reactContext, ReactVideoView view) - { - base.OnDropViewInstance(reactContext, view); - view.Dispose(); - } - - protected override ReactVideoView CreateViewInstance(ThemedReactContext reactContext) - { - return new ReactVideoView - { - HorizontalAlignment = HorizontalAlignment.Stretch, - }; - } - } -} diff --git a/windows/ReactNativeVideo.Net46/packages.config b/windows/ReactNativeVideo.Net46/packages.config deleted file mode 100644 index 2c209cee..00000000 --- a/windows/ReactNativeVideo.Net46/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/windows/ReactNativeVideo.sln b/windows/ReactNativeVideo.sln deleted file mode 100644 index fe86ec07..00000000 --- a/windows/ReactNativeVideo.sln +++ /dev/null @@ -1,49 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactNativeVideo.Net46", "ReactNativeVideo.Net46\ReactNativeVideo.Net46.csproj", "{2D8406AB-0674-42D3-8FE3-41D251403DF8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactNative.Net46", "..\node_modules\react-native-windows\ReactWindows\ReactNative.Net46\ReactNative.Net46.csproj", "{22CBFF9C-FE36-43E8-A246-266C7635E662}" -EndProject -Global - GlobalSection(SharedMSBuildProjectFiles) = preSolution - ..\node_modules\react-native-windows\ReactWindows\ReactNative.Shared\ReactNative.Shared.projitems*{22cbff9c-fe36-43e8-a246-266c7635e662}*SharedItemsImports = 4 - EndGlobalSection - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|ARM = Debug|ARM - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|ARM = Release|ARM - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Debug|ARM.ActiveCfg = Debug|x86 - {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Debug|x64.ActiveCfg = Debug|x64 - {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Debug|x64.Build.0 = Debug|x64 - {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Debug|x86.ActiveCfg = Debug|x64 - {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Debug|x86.Build.0 = Debug|x64 - {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Release|ARM.ActiveCfg = Release|x86 - {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Release|x64.ActiveCfg = Release|x64 - {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Release|x64.Build.0 = Release|x64 - {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Release|x86.ActiveCfg = Release|x86 - {2D8406AB-0674-42D3-8FE3-41D251403DF8}.Release|x86.Build.0 = Release|x86 - {22CBFF9C-FE36-43E8-A246-266C7635E662}.Debug|ARM.ActiveCfg = Debug|ARM - {22CBFF9C-FE36-43E8-A246-266C7635E662}.Debug|ARM.Build.0 = Debug|ARM - {22CBFF9C-FE36-43E8-A246-266C7635E662}.Debug|x64.ActiveCfg = Debug|x64 - {22CBFF9C-FE36-43E8-A246-266C7635E662}.Debug|x64.Build.0 = Debug|x64 - {22CBFF9C-FE36-43E8-A246-266C7635E662}.Debug|x86.ActiveCfg = Debug|x86 - {22CBFF9C-FE36-43E8-A246-266C7635E662}.Debug|x86.Build.0 = Debug|x86 - {22CBFF9C-FE36-43E8-A246-266C7635E662}.Release|ARM.ActiveCfg = Release|ARM - {22CBFF9C-FE36-43E8-A246-266C7635E662}.Release|ARM.Build.0 = Release|ARM - {22CBFF9C-FE36-43E8-A246-266C7635E662}.Release|x64.ActiveCfg = Release|x64 - {22CBFF9C-FE36-43E8-A246-266C7635E662}.Release|x64.Build.0 = Release|x64 - {22CBFF9C-FE36-43E8-A246-266C7635E662}.Release|x86.ActiveCfg = Release|x86 - {22CBFF9C-FE36-43E8-A246-266C7635E662}.Release|x86.Build.0 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/windows/ReactNativeVideo/Properties/AssemblyInfo.cs b/windows/ReactNativeVideo/Properties/AssemblyInfo.cs deleted file mode 100644 index 1d4241b5..00000000 --- a/windows/ReactNativeVideo/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ReactNativeVideo")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ReactNativeVideo")] -[assembly: AssemblyCopyright("Copyright © 2016")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] -[assembly: ComVisible(false)] \ No newline at end of file diff --git a/windows/ReactNativeVideo/Properties/ReactNativeVideo.rd.xml b/windows/ReactNativeVideo/Properties/ReactNativeVideo.rd.xml deleted file mode 100644 index 19ad73b1..00000000 --- a/windows/ReactNativeVideo/Properties/ReactNativeVideo.rd.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - diff --git a/windows/ReactNativeVideo/ReactNativeVideo.csproj b/windows/ReactNativeVideo/ReactNativeVideo.csproj deleted file mode 100644 index 3fd0e59d..00000000 --- a/windows/ReactNativeVideo/ReactNativeVideo.csproj +++ /dev/null @@ -1,116 +0,0 @@ - - - - - Debug - x86 - {E8F5F57F-757E-4237-AD23-F7A8755427CD} - Library - Properties - ReactNativeVideo - ReactNativeVideo - en-US - UAP - 10.0.14393.0 - 10.0.10586.0 - 14 - 512 - {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - - - x86 - true - bin\x86\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP - ;2008 - full - x86 - false - prompt - - - x86 - bin\x86\Release\ - TRACE;NETFX_CORE;WINDOWS_UWP - true - ;2008 - pdbonly - x86 - false - prompt - - - ARM - true - bin\ARM\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP - ;2008 - full - ARM - false - prompt - - - ARM - bin\ARM\Release\ - TRACE;NETFX_CORE;WINDOWS_UWP - true - ;2008 - pdbonly - ARM - false - prompt - - - x64 - true - bin\x64\Debug\ - DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP - ;2008 - full - x64 - false - prompt - - - x64 - bin\x64\Release\ - TRACE;NETFX_CORE;WINDOWS_UWP - true - ;2008 - pdbonly - x64 - false - prompt - - - - - - - - - - - - - - - - - {c7673ad5-e3aa-468c-a5fd-fa38154e205c} - ReactNative - - - - 14.0 - - - - diff --git a/windows/ReactNativeVideo/ReactVideoEventType.cs b/windows/ReactNativeVideo/ReactVideoEventType.cs deleted file mode 100644 index dd3f3feb..00000000 --- a/windows/ReactNativeVideo/ReactVideoEventType.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace ReactNativeVideo -{ - enum ReactVideoEventType - { - LoadStart, - Load, - Error, - Progress, - Seek, - End, - Stalled, - Resume, - ReadyForDisplay, - } -} diff --git a/windows/ReactNativeVideo/ReactVideoEventTypeExtensions.cs b/windows/ReactNativeVideo/ReactVideoEventTypeExtensions.cs deleted file mode 100644 index 5f2b63db..00000000 --- a/windows/ReactNativeVideo/ReactVideoEventTypeExtensions.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using static System.FormattableString; - -namespace ReactNativeVideo -{ - static class ReactVideoEventTypeExtensions - { - public static string GetEventName(this ReactVideoEventType eventType) - { - switch (eventType) - { - case ReactVideoEventType.LoadStart: - return "onVideoLoadStart"; - case ReactVideoEventType.Load: - return "onVideoLoad"; - case ReactVideoEventType.Error: - return "onVideoError"; - case ReactVideoEventType.Progress: - return "onVideoProgress"; - case ReactVideoEventType.Seek: - return "onVideoSeek"; - case ReactVideoEventType.End: - return "onVideoEnd"; - case ReactVideoEventType.Stalled: - return "onPlaybackStalled"; - case ReactVideoEventType.Resume: - return "onPlaybackResume"; - case ReactVideoEventType.ReadyForDisplay: - return "onReadyForDisplay"; - default: - throw new NotSupportedException( - Invariant($"No event name added for event type '{eventType}'.")); - } - } - } -} diff --git a/windows/ReactNativeVideo/ReactVideoPackage.cs b/windows/ReactNativeVideo/ReactVideoPackage.cs deleted file mode 100644 index b8cc654b..00000000 --- a/windows/ReactNativeVideo/ReactVideoPackage.cs +++ /dev/null @@ -1,30 +0,0 @@ -using ReactNative.Bridge; -using ReactNative.Modules.Core; -using ReactNative.UIManager; -using System; -using System.Collections.Generic; - -namespace ReactNativeVideo -{ - public class ReactVideoPackage : IReactPackage - { - public IReadOnlyList CreateJavaScriptModulesConfig() - { - return Array.Empty(); - } - - public IReadOnlyList CreateNativeModules(ReactContext reactContext) - { - return Array.Empty(); - - } - - public IReadOnlyList CreateViewManagers(ReactContext reactContext) - { - return new List - { - new ReactVideoViewManager(), - }; - } - } -} diff --git a/windows/ReactNativeVideo/ReactVideoView.cs b/windows/ReactNativeVideo/ReactVideoView.cs deleted file mode 100644 index 5a6c103f..00000000 --- a/windows/ReactNativeVideo/ReactVideoView.cs +++ /dev/null @@ -1,365 +0,0 @@ -using Newtonsoft.Json.Linq; -using ReactNative.UIManager; -using ReactNative.UIManager.Events; -using System; -using Windows.ApplicationModel.Core; -using Windows.Media.Core; -using Windows.Media.Playback; -using Windows.UI.Core; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; - -namespace ReactNativeVideo -{ - class ReactVideoView : MediaPlayerElement, IDisposable - { - public const string EVENT_PROP_SEEK_TIME = "seekTime"; - - private readonly DispatcherTimer _timer; - - private bool _isLoopingEnabled; - private bool _isPaused; - private bool _isMuted; - private bool _isUserControlEnabled; - private bool _isCompleted; - private double _volume; - private double _rate; - - public ReactVideoView() - { - _timer = new DispatcherTimer(); - _timer.Interval = TimeSpan.FromMilliseconds(250.0); - _timer.Start(); - } - - public new string Source - { - set - { - var uri = value; - - base.Source = MediaSource.CreateFromUri(new Uri(uri)); - - this.GetReactContext() - .GetNativeModule() - .EventDispatcher - .DispatchEvent( - new ReactVideoEvent( - ReactVideoEventType.LoadStart.GetEventName(), - this.GetTag(), - new JObject - { - { "src", uri } - })); - - ApplyModifiers(); - SubscribeEvents(); - } - } - - public bool IsLoopingEnabled - { - set - { - _isLoopingEnabled = value; - var mediaPlayer = MediaPlayer; - if (mediaPlayer != null) - { - mediaPlayer.IsLoopingEnabled = _isLoopingEnabled; - } - } - } - - public bool IsMuted - { - set - { - _isMuted = value; - var mediaPlayer = MediaPlayer; - if (mediaPlayer != null) - { - mediaPlayer.IsMuted = _isMuted; - } - } - } - - public bool IsPaused - { - set - { - _isPaused = value; - var mediaPlayer = MediaPlayer; - if (mediaPlayer != null) - { - if (_isPaused) - { - mediaPlayer.Pause(); - } - else - { - mediaPlayer.Play(); - } - } - } - } - - public bool IsUserControlEnabled - { - set - { - _isUserControlEnabled = value; - var mediaPlayer = MediaPlayer; - if (mediaPlayer != null) - { - mediaPlayer.SystemMediaTransportControls.IsEnabled = _isUserControlEnabled; - } - } - } - - public double Volume - { - set - { - _volume = value; - var mediaPlayer = MediaPlayer; - if (mediaPlayer != null) - { - mediaPlayer.Volume = _volume; - } - } - } - - public double Rate - { - set - { - _rate = value; - var mediaPlayer = MediaPlayer; - if (mediaPlayer != null) - { - mediaPlayer.PlaybackSession.PlaybackRate = _rate; - } - } - } - - public double ProgressUpdateInterval - { - set - { - _timer.Interval = TimeSpan.FromSeconds(value); - } - } - - public void Seek(double seek) - { - var mediaPlayer = MediaPlayer; - if (mediaPlayer != null) - { - mediaPlayer.PlaybackSession.Position = TimeSpan.FromSeconds(seek); - } - } - - public void Dispose() - { - var mediaPlayer = MediaPlayer; - if (mediaPlayer != null) - { - _timer.Tick -= OnTick; - mediaPlayer.MediaOpened -= OnMediaOpened; - mediaPlayer.MediaFailed -= OnMediaFailed; - mediaPlayer.MediaEnded -= OnMediaEnded; - mediaPlayer.PlaybackSession.BufferingStarted -= OnBufferingStarted; - mediaPlayer.PlaybackSession.BufferingEnded -= OnBufferingEnded; - MediaPlayer.PlaybackSession.SeekCompleted -= OnSeekCompleted; - } - - _timer.Stop(); - } - - private void ApplyModifiers() - { - IsLoopingEnabled = _isLoopingEnabled; - IsMuted = _isMuted; - IsPaused = _isPaused; - IsUserControlEnabled = _isUserControlEnabled; - Volume = _volume; - Rate = _rate; - } - - private void SubscribeEvents() - { - _timer.Tick += OnTick; - var mediaPlayer = MediaPlayer; - mediaPlayer.MediaOpened += OnMediaOpened; - mediaPlayer.MediaFailed += OnMediaFailed; - mediaPlayer.MediaEnded += OnMediaEnded; - mediaPlayer.PlaybackSession.BufferingStarted += OnBufferingStarted; - mediaPlayer.PlaybackSession.BufferingEnded += OnBufferingEnded; - mediaPlayer.PlaybackSession.SeekCompleted += OnSeekCompleted; - } - - private void OnTick(object sender, object e) - { - var mediaPlayer = MediaPlayer; - if (mediaPlayer != null && !_isCompleted && !_isPaused) - { - this.GetReactContext() - .GetNativeModule() - .EventDispatcher - .DispatchEvent( - new ReactVideoEvent( - ReactVideoEventType.Progress.GetEventName(), - this.GetTag(), - new JObject - { - { "currentTime", mediaPlayer.PlaybackSession.Position.TotalSeconds }, - { "playableDuration", 0.0 /* TODO */ } - })); - } - } - - private void OnMediaOpened(MediaPlayer sender, object args) - { - RunOnDispatcher(delegate - { - var width = sender.PlaybackSession.NaturalVideoWidth; - var height = sender.PlaybackSession.NaturalVideoHeight; - var orientation = (width > height) ? "landscape" : "portrait"; - var size = new JObject - { - { "width", width }, - { "height", height }, - { "orientation", orientation } - }; - - this.GetReactContext() - .GetNativeModule() - .EventDispatcher - .DispatchEvent( - new ReactVideoEvent( - ReactVideoEventType.Load.GetEventName(), - this.GetTag(), - new JObject - { - { "duration", sender.PlaybackSession.NaturalDuration.TotalSeconds }, - { "currentTime", sender.PlaybackSession.Position.TotalSeconds }, - { "naturalSize", size }, - { "canPlayFastForward", false }, - { "canPlaySlowForward", false }, - { "canPlaySlow", false }, - { "canPlayReverse", false }, - { "canStepBackward", false }, - { "canStepForward", false } - })); - }); - } - - private void OnMediaFailed(MediaPlayer sender, MediaPlayerFailedEventArgs args) - { - var errorData = new JObject - { - { "what", args.Error.ToString() }, - { "extra", args.ErrorMessage } - }; - - this.GetReactContext() - .GetNativeModule() - .EventDispatcher - .DispatchEvent( - new ReactVideoEvent( - ReactVideoEventType.Error.GetEventName(), - this.GetTag(), - new JObject - { - { "error", errorData } - })); - } - - private void OnMediaEnded(MediaPlayer sender, object args) - { - _isCompleted = true; - this.GetReactContext() - .GetNativeModule() - .EventDispatcher - .DispatchEvent( - new ReactVideoEvent( - ReactVideoEventType.End.GetEventName(), - this.GetTag(), - null)); - } - - private void OnBufferingStarted(MediaPlaybackSession sender, object args) - { - this.GetReactContext() - .GetNativeModule() - .EventDispatcher - .DispatchEvent( - new ReactVideoEvent( - ReactVideoEventType.Stalled.GetEventName(), - this.GetTag(), - new JObject())); - } - - private void OnBufferingEnded(MediaPlaybackSession sender, object args) - { - this.GetReactContext() - .GetNativeModule() - .EventDispatcher - .DispatchEvent( - new ReactVideoEvent( - ReactVideoEventType.Resume.GetEventName(), - this.GetTag(), - new JObject())); - } - - private void OnSeekCompleted(MediaPlaybackSession sender, object args) - { - this.GetReactContext() - .GetNativeModule() - .EventDispatcher.DispatchEvent( - new ReactVideoEvent( - ReactVideoEventType.Seek.GetEventName(), - this.GetTag(), - new JObject())); - } - - private static async void RunOnDispatcher(DispatchedHandler action) - { - await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, action).AsTask().ConfigureAwait(false); - } - - class ReactVideoEvent : Event - { - private readonly string _eventName; - private readonly JObject _eventData; - - public ReactVideoEvent(string eventName, int viewTag, JObject eventData) - : base(viewTag) - { - _eventName = eventName; - _eventData = eventData; - } - - public override string EventName - { - get - { - return _eventName; - } - } - - public override bool CanCoalesce - { - get - { - return false; - } - } - - public override void Dispatch(RCTEventEmitter eventEmitter) - { - eventEmitter.receiveEvent(ViewTag, EventName, _eventData); - } - } - } -} diff --git a/windows/ReactNativeVideo/ReactVideoViewManager.cs b/windows/ReactNativeVideo/ReactVideoViewManager.cs deleted file mode 100644 index e93456c3..00000000 --- a/windows/ReactNativeVideo/ReactVideoViewManager.cs +++ /dev/null @@ -1,137 +0,0 @@ -using Newtonsoft.Json.Linq; -using ReactNative.UIManager; -using ReactNative.UIManager.Annotations; -using System; -using System.Collections.Generic; -using System.Linq; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Media; - -namespace ReactNativeVideo -{ - class ReactVideoViewManager : SimpleViewManager - { - public override string Name - { - get - { - return "RCTVideo"; - } - } - - public override IReadOnlyDictionary ExportedViewConstants - { - get - { - return new Dictionary - { - { "ScaleNone", ((int)Stretch.None).ToString() }, - { "ScaleToFill", ((int)Stretch.UniformToFill).ToString() }, - { "ScaleAspectFit", ((int)Stretch.Uniform).ToString() }, - { "ScaleAspectFill", ((int)Stretch.Fill).ToString() }, - }; - } - } - - public override IReadOnlyDictionary ExportedCustomDirectEventTypeConstants - { - get - { - var events = new Dictionary(); - var eventTypes = Enum.GetValues(typeof(ReactVideoEventType)).OfType(); - foreach (var eventType in eventTypes) - { - events.Add(eventType.GetEventName(), new Dictionary - { - { "registrationName", eventType.GetEventName() }, - }); - } - - return events; - } - } - - [ReactProp("src")] - public void SetSource(ReactVideoView view, JObject source) - { - view.Source = source.Value("uri"); - } - - [ReactProp("resizeMode")] - public void SetResizeMode(ReactVideoView view, string resizeMode) - { - view.Stretch = (Stretch)int.Parse(resizeMode); - } - - [ReactProp("repeat")] - public void SetRepeat(ReactVideoView view, bool repeat) - { - view.IsLoopingEnabled = repeat; - } - - [ReactProp("paused")] - public void SetPaused(ReactVideoView view, bool paused) - { - view.IsPaused = paused; - } - - [ReactProp("muted")] - public void SetMuted(ReactVideoView view, bool muted) - { - view.IsMuted = muted; - } - - [ReactProp("volume", DefaultDouble = 1.0)] - public void SetVolume(ReactVideoView view, double volume) - { - view.Volume = volume; - } - - [ReactProp("seek")] - public void SetSeek(ReactVideoView view, double? seek) - { - if (seek.HasValue) - { - view.Seek(seek.Value); - } - } - - [ReactProp("rate", DefaultDouble = 1.0)] - public void SetPlaybackRate(ReactVideoView view, double rate) - { - view.Rate = rate; - } - - [ReactProp("playInBackground")] - public void SetPlayInBackground(ReactVideoView view, bool playInBackground) - { - throw new NotImplementedException("Play in background has not been implemented on Windows."); - } - - [ReactProp("controls")] - public void SetControls(ReactVideoView view, bool controls) - { - view.IsUserControlEnabled = controls; - } - - [ReactProp("progressUpdateInterval")] - public void SetProgressUpdateInterval(ReactVideoView view, double progressUpdateInterval) - { - view.ProgressUpdateInterval = progressUpdateInterval; - } - - public override void OnDropViewInstance(ThemedReactContext reactContext, ReactVideoView view) - { - base.OnDropViewInstance(reactContext, view); - view.Dispose(); - } - - protected override ReactVideoView CreateViewInstance(ThemedReactContext reactContext) - { - return new ReactVideoView - { - HorizontalAlignment = HorizontalAlignment.Stretch, - }; - } - } -} diff --git a/windows/ReactNativeVideo/project.json b/windows/ReactNativeVideo/project.json deleted file mode 100644 index 8eec893a..00000000 --- a/windows/ReactNativeVideo/project.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "dependencies": { - "Microsoft.NETCore.UniversalWindowsPlatform": "5.2.2", - "Newtonsoft.Json": "10.0.3" - }, - "frameworks": { - "uap10.0": {} - }, - "runtimes": { - "win10-arm": {}, - "win10-arm-aot": {}, - "win10-x86": {}, - "win10-x86-aot": {}, - "win10-x64": {}, - "win10-x64-aot": {} - } -} diff --git a/windows/ReactNativeVideoCPP/PropertySheet.props b/windows/ReactNativeVideoCPP/PropertySheet.props new file mode 100644 index 00000000..3e15bb90 --- /dev/null +++ b/windows/ReactNativeVideoCPP/PropertySheet.props @@ -0,0 +1,16 @@ + + + + + + + + \ No newline at end of file diff --git a/windows/ReactNativeVideoCPP/ReactNativeVideoCPP.def b/windows/ReactNativeVideoCPP/ReactNativeVideoCPP.def new file mode 100644 index 00000000..8c1a0293 --- /dev/null +++ b/windows/ReactNativeVideoCPP/ReactNativeVideoCPP.def @@ -0,0 +1,3 @@ +EXPORTS +DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE +DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/windows/ReactNativeVideoCPP/ReactNativeVideoCPP.vcxproj b/windows/ReactNativeVideoCPP/ReactNativeVideoCPP.vcxproj new file mode 100644 index 00000000..ae12f7a7 --- /dev/null +++ b/windows/ReactNativeVideoCPP/ReactNativeVideoCPP.vcxproj @@ -0,0 +1,157 @@ + + + + + true + true + true + {765365e4-9553-4900-9f69-e26d4309c8da} + ReactNativeVideoCPP + ReactNativeVideoCPP + en-US + 14.0 + true + Windows Store + 10.0 + 10.0.18362.0 + 10.0.15063.0 + + + + + Debug + ARM + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + Win32 + + + Release + x64 + + + + DynamicLibrary + v140 + v141 + v142 + Unicode + false + + + true + true + + + false + true + false + + + + + + + + + + + + + + + + + + Use + pch.h + $(IntDir)pch.pch + Level4 + %(AdditionalOptions) /bigobj + + /DWINRT_NO_MAKE_DETECTION %(AdditionalOptions) + 28204 + _WINRT_DLL;%(PreprocessorDefinitions) + $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) + + + Console + true + ReactNativeVideoCPP.def + + + + + _DEBUG;%(PreprocessorDefinitions) + + + + + NDEBUG;%(PreprocessorDefinitions) + + + + + ReactVideoView.idl + + + + + ReactPackageProvider.idl + + + + + ReactVideoView.idl + + + + Create + + + ReactPackageProvider.idl + + + + + + + + + + + + + + + + + {f7d32bd0-2749-483e-9a0d-1635ef7e3136} + false + + + + + + + + + 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}. + + + + + \ No newline at end of file diff --git a/windows/ReactNativeVideoCPP/ReactNativeVideoCPP.vcxproj.filters b/windows/ReactNativeVideoCPP/ReactNativeVideoCPP.vcxproj.filters new file mode 100644 index 00000000..de60c2b0 --- /dev/null +++ b/windows/ReactNativeVideoCPP/ReactNativeVideoCPP.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + accd3aa8-1ba0-4223-9bbe-0c431709210b + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + {926ab91d-31b4-48c3-b9a4-e681349f27f0} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/windows/ReactNativeVideoCPP/ReactPackageProvider.cpp b/windows/ReactNativeVideoCPP/ReactPackageProvider.cpp new file mode 100644 index 00000000..afa5dde3 --- /dev/null +++ b/windows/ReactNativeVideoCPP/ReactPackageProvider.cpp @@ -0,0 +1,17 @@ +#include "pch.h" +#include "ReactPackageProvider.h" +#if __has_include("ReactPackageProvider.g.cpp") +#include "ReactPackageProvider.g.cpp" +#endif + +#include "ReactVideoViewManager.h" + +using namespace winrt::Microsoft::ReactNative; + +namespace winrt::ReactNativeVideoCPP::implementation { + +void ReactPackageProvider::CreatePackage(IReactPackageBuilder const &packageBuilder) noexcept { + packageBuilder.AddViewManager(L"ReactVideoViewManager", []() { return winrt::make(); }); +} + +} // namespace winrt::ReactNativeVideoCPP::implementation diff --git a/windows/ReactNativeVideoCPP/ReactPackageProvider.h b/windows/ReactNativeVideoCPP/ReactPackageProvider.h new file mode 100644 index 00000000..a53e0ccd --- /dev/null +++ b/windows/ReactNativeVideoCPP/ReactPackageProvider.h @@ -0,0 +1,20 @@ +#pragma once +#include "ReactPackageProvider.g.h" + +using namespace winrt::Microsoft::ReactNative; + +namespace winrt::ReactNativeVideoCPP::implementation { + +struct ReactPackageProvider : ReactPackageProviderT { + ReactPackageProvider() = default; + + void CreatePackage(IReactPackageBuilder const &packageBuilder) noexcept; +}; + +} // namespace winrt::ReactNativeVideoCPP::implementation + +namespace winrt::ReactNativeVideoCPP::factory_implementation { + +struct ReactPackageProvider : ReactPackageProviderT {}; + +} // namespace winrt::ReactNativeVideoCPP::factory_implementation diff --git a/windows/ReactNativeVideoCPP/ReactPackageProvider.idl b/windows/ReactNativeVideoCPP/ReactPackageProvider.idl new file mode 100644 index 00000000..79a74ceb --- /dev/null +++ b/windows/ReactNativeVideoCPP/ReactPackageProvider.idl @@ -0,0 +1,7 @@ +namespace ReactNativeVideoCPP { +[webhosthidden] +[default_interface] +runtimeclass ReactPackageProvider : Microsoft.ReactNative.IReactPackageProvider { + ReactPackageProvider(); +}; +} // namespace ReactNativeVideoCPP diff --git a/windows/ReactNativeVideoCPP/ReactVideoView.cpp b/windows/ReactNativeVideoCPP/ReactVideoView.cpp new file mode 100644 index 00000000..b9a1aa53 --- /dev/null +++ b/windows/ReactNativeVideoCPP/ReactVideoView.cpp @@ -0,0 +1,244 @@ +#include "pch.h" +#include "ReactVideoView.h" +#include "ReactVideoView.g.cpp" +#include "NativeModules.h" + +using namespace winrt; +using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; + +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Media; +using namespace Windows::UI::Xaml::Controls; +using namespace Windows::UI::Core; +using namespace Windows::Media::Core; +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(); + + 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); + } + }); + 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); + } + }); + + 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) { + if (auto self = ref.get()) { + self->OnBufferingStarted(sender, 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); + } + }); + + 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); + } + }); + + 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; + + 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(); + } + + 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::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::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::Set_ProgressUpdateInterval(int64_t 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); + } +} + +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(); + } + } + } +} + +void ReactVideoView::Set_AutoPlay(bool autoPlay) { + m_player.AutoPlay(autoPlay); +} + +void ReactVideoView::Set_Muted(bool 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); +} + +void ReactVideoView::Set_FullScreen(bool fullScreen) { + m_fullScreen = fullScreen; + IsFullWindow(m_fullScreen); + + 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); + } +} + +void ReactVideoView::Set_Position(double position) { + m_position = position; + if (m_player != nullptr) { + std::chrono::seconds duration(static_cast(m_position)); + m_player.PlaybackSession().Position(duration); + } +} + +bool ReactVideoView::IsPlaying(MediaPlaybackState currentState) { + return ( + currentState == MediaPlaybackState::Buffering || + currentState == MediaPlaybackState::Opening || + currentState == MediaPlaybackState::Playing + ); +} + +void ReactVideoView::runOnQueue(std::function&& func) { + m_uiDispatcher.RunAsync( + winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, [func = std::move(func)]() { func(); }); +} + +} // namespace winrt::ReactNativeVideoCPP::implementation diff --git a/windows/ReactNativeVideoCPP/ReactVideoView.h b/windows/ReactNativeVideoCPP/ReactVideoView.h new file mode 100644 index 00000000..39201e5c --- /dev/null +++ b/windows/ReactNativeVideoCPP/ReactVideoView.h @@ -0,0 +1,56 @@ +#pragma once +#include "ReactVideoView.g.h" +#include +using namespace winrt; +using namespace Microsoft::ReactNative; + +namespace winrt::ReactNativeVideoCPP::implementation { +struct ReactVideoView : ReactVideoViewT { + public: + ReactVideoView(winrt::Microsoft::ReactNative::IReactContext const &reactContext); + void Set_UriString(hstring const &value); + void Set_IsLoopingEnabled(bool value); + void Set_Paused(bool isPaused); + void Set_Muted(bool isMuted); + void Set_Volume(double volume); + void Set_Position(double position); + void Set_Controls(bool useControls); + void Set_FullScreen(bool fullScreen); + void Set_ProgressUpdateInterval(int64_t interval); + void Set_AutoPlay(bool autoPlay); + + private: + hstring m_uriString; + bool m_isLoopingEnabled = false; + bool m_isPaused = true; + bool m_isMuted = false; + bool m_useControls = false; + bool m_fullScreen = false; + double m_volume = 0; + double m_position = 0; + Windows::UI::Xaml::DispatcherTimer m_timer; + Windows::Media::Playback::MediaPlayer m_player = nullptr; + Windows::UI::Core::CoreDispatcher m_uiDispatcher = nullptr; + Microsoft::ReactNative::IReactContext m_reactContext{nullptr}; + + Windows::Media::Playback::MediaPlayer::MediaOpened_revoker m_mediaOpenedToken{}; + Windows::Media::Playback::MediaPlayer::MediaFailed_revoker m_mediaFailedToken{}; + Windows::Media::Playback::MediaPlayer::MediaEnded_revoker m_mediaEndedToken{}; + Windows::Media::Playback::MediaPlaybackSession::BufferingStarted_revoker m_bufferingStartedToken{}; + Windows::Media::Playback::MediaPlaybackSession::BufferingEnded_revoker m_bufferingEndedToken{}; + Windows::Media::Playback::MediaPlaybackSession::SeekCompleted_revoker m_seekCompletedToken{}; + + bool IsPlaying(Windows::Media::Playback::MediaPlaybackState currentState); + void OnMediaOpened(IInspectable const &sender, IInspectable const &args); + void OnMediaFailed(IInspectable const &sender, IInspectable const &args); + void OnMediaEnded(IInspectable const &sender, IInspectable const &); + void OnBufferingStarted(IInspectable const &sender, IInspectable const &); + void OnBufferingEnded(IInspectable const &sender, IInspectable const &); + void OnSeekCompleted(IInspectable const &sender, IInspectable const &); + + void runOnQueue(std::function &&func); +}; +} // namespace winrt::ReactNativeVideoCPP::implementation +namespace winrt::ReactNativeVideoCPP::factory_implementation { +struct ReactVideoView : ReactVideoViewT {}; +} // namespace winrt::ReactNativeVideoCPP::factory_implementation diff --git a/windows/ReactNativeVideoCPP/ReactVideoView.idl b/windows/ReactNativeVideoCPP/ReactVideoView.idl new file mode 100644 index 00000000..a1127877 --- /dev/null +++ b/windows/ReactNativeVideoCPP/ReactVideoView.idl @@ -0,0 +1,16 @@ +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 diff --git a/windows/ReactNativeVideoCPP/ReactVideoViewManager.cpp b/windows/ReactNativeVideoCPP/ReactVideoViewManager.cpp new file mode 100644 index 00000000..b31a38ad --- /dev/null +++ b/windows/ReactNativeVideoCPP/ReactVideoViewManager.cpp @@ -0,0 +1,110 @@ +#include "pch.h" +#include "ReactVideoViewManager.h" +#include "NativeModules.h" +#include "ReactVideoView.h" + +namespace winrt::ReactNativeVideoCPP::implementation { + +ReactVideoViewManager::ReactVideoViewManager() {} + +// IViewManager +hstring ReactVideoViewManager::Name() noexcept { + return L"RCTVideo"; +} + +FrameworkElement ReactVideoViewManager::CreateView() noexcept { + auto reactVideoView = winrt::ReactNativeVideoCPP::ReactVideoView(m_reactContext); + return reactVideoView; +} + +// IViewManagerWithReactContext +IReactContext ReactVideoViewManager::ReactContext() noexcept { + return m_reactContext; +} + +void ReactVideoViewManager::ReactContext(IReactContext reactContext) noexcept { + m_reactContext = reactContext; +} + +// IViewManagerWithExportedViewConstants +winrt::Microsoft::ReactNative::ConstantProviderDelegate ReactVideoViewManager::ExportedViewConstants() noexcept { + return [](winrt::Microsoft::ReactNative::IJSValueWriter const &constantWriter) { + WriteProperty(constantWriter, L"ScaleNone", to_hstring(std::to_string((int)Stretch::None))); + WriteProperty(constantWriter, L"ScaleToFill", to_hstring(std::to_string((int)Stretch::UniformToFill))); + WriteProperty(constantWriter, L"ScaleAspectFit", to_hstring(std::to_string((int)Stretch::Uniform))); + WriteProperty(constantWriter, L"ScaleAspectFill", to_hstring(std::to_string((int)Stretch::Fill))); + }; +} + +// IViewManagerWithNativeProperties +IMapView ReactVideoViewManager::NativeProps() noexcept { + auto nativeProps = winrt::single_threaded_map(); + nativeProps.Insert(L"src", ViewManagerPropertyType::Map); + nativeProps.Insert(L"resizeMode", ViewManagerPropertyType::String); + nativeProps.Insert(L"repeat", ViewManagerPropertyType::Boolean); + nativeProps.Insert(L"paused", ViewManagerPropertyType::Boolean); + nativeProps.Insert(L"muted", ViewManagerPropertyType::Boolean); + nativeProps.Insert(L"volume", ViewManagerPropertyType::Number); + nativeProps.Insert(L"seek", ViewManagerPropertyType::Number); + nativeProps.Insert(L"controls", ViewManagerPropertyType::Boolean); + nativeProps.Insert(L"fullscreen", ViewManagerPropertyType::Boolean); + nativeProps.Insert(L"progressUpdateInterval", ViewManagerPropertyType::Number); + + return nativeProps.GetView(); +} + +void ReactVideoViewManager::UpdateProperties( + FrameworkElement const &view, + IJSValueReader const &propertyMapReader) noexcept { + if (auto reactVideoView = view.try_as()) { + const JSValueObject &propertyMap = JSValue::ReadObjectFrom(propertyMapReader); + + for (auto const &pair : propertyMap) { + auto const &propertyName = pair.first; + auto const &propertyValue = pair.second; + if (!propertyValue.IsNull()) { + if (propertyName == "src") { + auto const &srcMap = propertyValue.Object(); + auto const &uri = srcMap.at("uri"); + reactVideoView.Set_UriString(to_hstring(uri.String())); + } else if (propertyName == "resizeMode") { + reactVideoView.Stretch(static_cast(std::stoul(propertyValue.String()))); + } else if (propertyName == "repeat") { + reactVideoView.Set_IsLoopingEnabled(propertyValue.Boolean()); + } else if (propertyName == "paused") { + m_paused = propertyValue.Boolean(); + reactVideoView.Set_Paused(m_paused); + } else if (propertyName == "muted") { + reactVideoView.Set_Muted(propertyValue.Boolean()); + } else if (propertyName == "volume") { + reactVideoView.Set_Volume(propertyValue.Double()); + } else if (propertyName == "seek") { + reactVideoView.Set_Position(propertyValue.Double()); + } else if (propertyName == "controls") { + reactVideoView.Set_Controls(propertyValue.Boolean()); + } else if (propertyName == "fullscreen") { + reactVideoView.Set_FullScreen(propertyValue.Boolean()); + } else if (propertyName == "progressUpdateInterval") { + reactVideoView.Set_ProgressUpdateInterval(propertyValue.Int64()); + } + } + } + reactVideoView.Set_AutoPlay(!m_paused); // auto play on pause false or not set. + } +} + +// IViewManagerWithExportedEventTypeConstants +ConstantProviderDelegate ReactVideoViewManager::ExportedCustomBubblingEventTypeConstants() noexcept { + return nullptr; +} + +ConstantProviderDelegate ReactVideoViewManager::ExportedCustomDirectEventTypeConstants() noexcept { + return [](winrt::Microsoft::ReactNative::IJSValueWriter const &constantWriter) { + WriteCustomDirectEventTypeConstant(constantWriter, "Load"); + WriteCustomDirectEventTypeConstant(constantWriter, "End"); + WriteCustomDirectEventTypeConstant(constantWriter, "Seek"); + WriteCustomDirectEventTypeConstant(constantWriter, "Progress"); + }; +} + +} // namespace winrt::ReactNativeVideoCPP::implementation diff --git a/windows/ReactNativeVideoCPP/ReactVideoViewManager.h b/windows/ReactNativeVideoCPP/ReactVideoViewManager.h new file mode 100644 index 00000000..3c01fcdf --- /dev/null +++ b/windows/ReactNativeVideoCPP/ReactVideoViewManager.h @@ -0,0 +1,55 @@ +#pragma once + +#include "winrt/Microsoft.ReactNative.h" + +using namespace winrt; +using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; + +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Media; +using namespace Windows::UI::Xaml::Controls; +using namespace Windows::Media::Core; + +namespace winrt::ReactNativeVideoCPP::implementation { + +struct ReactVideoViewManager : winrt::implements< + ReactVideoViewManager, + winrt::Microsoft::ReactNative::IViewManager, + winrt::Microsoft::ReactNative::IViewManagerWithReactContext, + winrt::Microsoft::ReactNative::IViewManagerWithExportedViewConstants, + winrt::Microsoft::ReactNative::IViewManagerWithNativeProperties, + winrt::Microsoft::ReactNative::IViewManagerWithExportedEventTypeConstants> { + public: + ReactVideoViewManager(); + // IViewManager + winrt::hstring Name() noexcept; + FrameworkElement CreateView() noexcept; + + // IViewManagerWithReactContext + winrt::Microsoft::ReactNative::IReactContext ReactContext() noexcept; + void ReactContext(winrt::Microsoft::ReactNative::IReactContext reactContext) noexcept; + + // IViewManagerWithNativeProperties + winrt::Windows::Foundation::Collections:: + IMapView + NativeProps() noexcept; + + void UpdateProperties( + winrt::Windows::UI::Xaml::FrameworkElement const &view, + winrt::Microsoft::ReactNative::IJSValueReader const &propertyMapReader) noexcept; + + // IViewManagerWithExportedViewConstants + winrt::Microsoft::ReactNative::ConstantProviderDelegate ExportedViewConstants() noexcept; + + // IViewManagerWithExportedEventTypeConstants + winrt::Microsoft::ReactNative::ConstantProviderDelegate ExportedCustomBubblingEventTypeConstants() noexcept; + + winrt::Microsoft::ReactNative::ConstantProviderDelegate ExportedCustomDirectEventTypeConstants() noexcept; + + private: + winrt::Microsoft::ReactNative::IReactContext m_reactContext{nullptr}; + bool m_paused = false; +}; + +} // namespace winrt::ReactNativeVideoCPP::implementation diff --git a/windows/ReactNativeVideoCPP/packages.config b/windows/ReactNativeVideoCPP/packages.config new file mode 100644 index 00000000..9a69657f --- /dev/null +++ b/windows/ReactNativeVideoCPP/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/windows/ReactNativeVideoCPP/pch.cpp b/windows/ReactNativeVideoCPP/pch.cpp new file mode 100644 index 00000000..e0d2ef1a --- /dev/null +++ b/windows/ReactNativeVideoCPP/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/windows/ReactNativeVideoCPP/pch.h b/windows/ReactNativeVideoCPP/pch.h new file mode 100644 index 00000000..623de244 --- /dev/null +++ b/windows/ReactNativeVideoCPP/pch.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include