Initial WPF Support (#385)
* initial support for WPF * update readme with WPF specific instructions * remove autogenerated .gitattributes file * reference RNW NPM package instead of hard-coded local reference
This commit is contained in:
parent
d48d7efc5d
commit
ebc6617ba4
@ -80,14 +80,18 @@ Add the `ReactNativeVideo` project to your solution.
|
||||
|
||||
1. Open the solution in Visual Studio 2015
|
||||
2. Right-click Solution icon in Solution Explorer > Add > Existing Project...
|
||||
3. Select `node_modules\react-native-video\windows\ReactNativeVideo\ReactNativeVideo.csproj`
|
||||
3.
|
||||
UWP: Select `node_modules\react-native-video\windows\ReactNativeVideo\ReactNativeVideo.csproj`
|
||||
WPF: Select `node_modules\react-native-video\windows\ReactNativeVideo.Net46\ReactNativeVideo.Net46.csproj`
|
||||
|
||||
**windows/myapp/myapp.csproj**
|
||||
|
||||
Add a reference to `ReactNativeVideo` to your main application project. From Visual Studio 2015:
|
||||
|
||||
1. Right-click main application project > Add > Reference...
|
||||
2. Check `ReactNativeVideo` from Solution Projects.
|
||||
2.
|
||||
UWP: Check `ReactNativeVideo` from Solution Projects.
|
||||
WPF: Check `ReactNativeVideo.Net46` from Solution Projects.
|
||||
|
||||
**MainPage.cs**
|
||||
|
||||
|
@ -27,7 +27,8 @@
|
||||
"eslint-config-airbnb": "4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"keymirror": "0.1.1"
|
||||
"keymirror": "0.1.1",
|
||||
"react-native-windows": "0.41.0-rc.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node_modules/.bin/eslint *.js"
|
||||
|
36
windows/ReactNativeVideo.Net46/Properties/AssemblyInfo.cs
Normal file
36
windows/ReactNativeVideo.Net46/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
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")]
|
74
windows/ReactNativeVideo.Net46/ReactNativeVideo.Net46.csproj
Normal file
74
windows/ReactNativeVideo.Net46/ReactNativeVideo.Net46.csproj
Normal file
@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{2D8406AB-0674-42D3-8FE3-41D251403DF8}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ReactNativeVideo.Net46</RootNamespace>
|
||||
<AssemblyName>ReactNativeVideo.Net46</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>$(SolutionDir)\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xaml" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ReactVideoEventType.cs" />
|
||||
<Compile Include="ReactVideoEventTypeExtensions.cs" />
|
||||
<Compile Include="ReactVideoPackage.cs" />
|
||||
<Compile Include="ReactVideoView.cs" />
|
||||
<Compile Include="ReactVideoViewManager.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(SolutionDir)\..\node_modules\react-native-windows\ReactWindows\ReactNative.Net46\ReactNative.Net46.csproj">
|
||||
<Project>{22CBFF9C-FE36-43E8-A246-266C7635E662}</Project>
|
||||
<Name>ReactNative.Net46</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
15
windows/ReactNativeVideo.Net46/ReactVideoEventType.cs
Normal file
15
windows/ReactNativeVideo.Net46/ReactVideoEventType.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace ReactNativeVideo
|
||||
{
|
||||
enum ReactVideoEventType
|
||||
{
|
||||
LoadStart,
|
||||
Load,
|
||||
Error,
|
||||
Progress,
|
||||
Seek,
|
||||
End,
|
||||
Stalled,
|
||||
Resume,
|
||||
ReadyForDisplay,
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
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}'."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
windows/ReactNativeVideo.Net46/ReactVideoPackage.cs
Normal file
30
windows/ReactNativeVideo.Net46/ReactVideoPackage.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using ReactNative.Bridge;
|
||||
using ReactNative.Modules.Core;
|
||||
using ReactNative.UIManager;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ReactNativeVideo
|
||||
{
|
||||
public class ReactVideoPackage : IReactPackage
|
||||
{
|
||||
public IReadOnlyList<Type> CreateJavaScriptModulesConfig()
|
||||
{
|
||||
return Array.Empty<Type>();
|
||||
}
|
||||
|
||||
public IReadOnlyList<INativeModule> CreateNativeModules(ReactContext reactContext)
|
||||
{
|
||||
return Array.Empty<INativeModule>();
|
||||
|
||||
}
|
||||
|
||||
public IReadOnlyList<IViewManager> CreateViewManagers(ReactContext reactContext)
|
||||
{
|
||||
return new List<IViewManager>
|
||||
{
|
||||
new ReactVideoViewManager(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
359
windows/ReactNativeVideo.Net46/ReactVideoView.cs
Normal file
359
windows/ReactNativeVideo.Net46/ReactVideoView.cs
Normal file
@ -0,0 +1,359 @@
|
||||
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<UIManagerModule>()
|
||||
.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<UIManagerModule>()
|
||||
.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<UIManagerModule>()
|
||||
.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<UIManagerModule>()
|
||||
.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<UIManagerModule>()
|
||||
.EventDispatcher
|
||||
.DispatchEvent(
|
||||
new ReactVideoEvent(
|
||||
ReactVideoEventType.End.GetEventName(),
|
||||
this.GetTag(),
|
||||
null));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnBufferingStarted(object sender, EventArgs args)
|
||||
{
|
||||
this.GetReactContext()
|
||||
.GetNativeModule<UIManagerModule>()
|
||||
.EventDispatcher
|
||||
.DispatchEvent(
|
||||
new ReactVideoEvent(
|
||||
ReactVideoEventType.Stalled.GetEventName(),
|
||||
this.GetTag(),
|
||||
new JObject()));
|
||||
}
|
||||
|
||||
private void OnBufferingEnded(object sender, EventArgs args)
|
||||
{
|
||||
this.GetReactContext()
|
||||
.GetNativeModule<UIManagerModule>()
|
||||
.EventDispatcher
|
||||
.DispatchEvent(
|
||||
new ReactVideoEvent(
|
||||
ReactVideoEventType.Resume.GetEventName(),
|
||||
this.GetTag(),
|
||||
new JObject()));
|
||||
}
|
||||
|
||||
private void OnSeekCompleted(object sender, EventArgs args)
|
||||
{
|
||||
this.GetReactContext()
|
||||
.GetNativeModule<UIManagerModule>()
|
||||
.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, TimeSpan.FromTicks(Environment.TickCount))
|
||||
{
|
||||
_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
139
windows/ReactNativeVideo.Net46/ReactVideoViewManager.cs
Normal file
139
windows/ReactNativeVideo.Net46/ReactVideoViewManager.cs
Normal file
@ -0,0 +1,139 @@
|
||||
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<ReactVideoView>
|
||||
{
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "RCTVideo";
|
||||
}
|
||||
}
|
||||
|
||||
public override IReadOnlyDictionary<string, object> ExportedViewConstants
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Dictionary<string, object>
|
||||
{
|
||||
{ "ScaleNone", ((int)Stretch.None).ToString() },
|
||||
{ "ScaleToFill", ((int)Stretch.UniformToFill).ToString() },
|
||||
{ "ScaleAspectFit", ((int)Stretch.Uniform).ToString() },
|
||||
{ "ScaleAspectFill", ((int)Stretch.Fill).ToString() },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public override IReadOnlyDictionary<string, object> ExportedCustomDirectEventTypeConstants
|
||||
{
|
||||
get
|
||||
{
|
||||
var events = new Dictionary<string, object>();
|
||||
var eventTypes = Enum.GetValues(typeof(ReactVideoEventType)).OfType<ReactVideoEventType>();
|
||||
foreach (var eventType in eventTypes)
|
||||
{
|
||||
events.Add(eventType.GetEventName(), new Dictionary<string, object>
|
||||
{
|
||||
{ "registrationName", eventType.GetEventName() },
|
||||
});
|
||||
}
|
||||
|
||||
return events;
|
||||
}
|
||||
}
|
||||
|
||||
[ReactProp("src")]
|
||||
public void SetSource(ReactVideoView view, JObject source)
|
||||
{
|
||||
view.Source = source.Value<string>("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,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
4
windows/ReactNativeVideo.Net46/packages.config
Normal file
4
windows/ReactNativeVideo.Net46/packages.config
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net46" />
|
||||
</packages>
|
49
windows/ReactNativeVideo.sln
Normal file
49
windows/ReactNativeVideo.sln
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
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
|
Loading…
Reference in New Issue
Block a user