Skip to content
This repository was archived by the owner on Nov 8, 2019. It is now read-only.

Implemented SeekTo method. #180

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<TargetFrameworkVersion>v8.1</TargetFrameworkVersion>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<ReleaseVersion>0.1.1</ReleaseVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
Expand Down Expand Up @@ -140,7 +141,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Octane.Xamarin.Forms.VideoPlayer\Octane.Xamarin.Forms.VideoPlayer.csproj">
<Project>{6f36403b-c460-4a84-9c7a-e90f689576bd}</Project>
<Project>{353C7A43-D286-4F96-A221-363157CF20BC}</Project>
<Name>Octane.Xamarin.Forms.VideoPlayer</Name>
</ProjectReference>
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public virtual bool CanPlay()
{
var control = Control;
return control != null && (control.Status == MediaPlayerStatus.Prepared
|| control.Status == MediaPlayerStatus.Paused);
|| control.Status == MediaPlayerStatus.Paused || control.Status == MediaPlayerStatus.PlaybackCompleted);
}

/// <summary>
Expand Down Expand Up @@ -156,6 +156,39 @@ public virtual bool CanSeek(int time)
|| (time < 0 && Control.CanSeekBackward() && (Control.CurrentPosition + time) >= 0));
}

/// <summary>
/// Seeks to a specific position on the playback stream.
/// </summary>
/// <param name="time">The time in milliseconds.</param>
public virtual void SeekTo(int time)
{
if (CanSeekTo(time))
{
var control = Control;

if (control != null)
{
var currentTime = control.CurrentPosition;
Log.Info($"SEEK: CurrentTime={currentTime}; NewTime={time}");
control.SeekTo(time);
Element.SetValue(VideoPlayer.CurrentTimePropertyKey,
TimeSpan.FromMilliseconds(control.CurrentPosition));
}
}
}

/// <summary>
/// Determines if the video player instance can seek to a given position.
/// </summary>
/// <param name="time">The time in milliseconds.</param>
/// <returns></returns>
/// <c>true</c> if this instance can stop; otherwise, <c>false</c>.
public virtual bool CanSeekTo(int time)
{
var control = Control;
return control != null && time >= 0 && time <= control.CurrentPosition;
}

#endregion

#region ViewRenderer Overrides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<ReleaseVersion>0.1.1</ReleaseVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ public virtual bool CanSeek(int time)
|| (time < 0 && control.CanSeek && (control.Position.Subtract(TimeSpan.FromSeconds(absoluteTime)) >= TimeSpan.Zero)));
}

public virtual void SeekTo(int time) { }// TODO: Implement for UWP

public virtual bool CanSeekTo(int time) => true;

#endregion

#region ViewRenderer Overrides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<AssemblyName>Octane.Xamarin.Forms.VideoPlayer.iOS</AssemblyName>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<ReleaseVersion>0.1.1</ReleaseVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
Expand Down Expand Up @@ -67,7 +68,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Octane.Xamarin.Forms.VideoPlayer\Octane.Xamarin.Forms.VideoPlayer.csproj">
<Project>{6f36403b-c460-4a84-9c7a-e90f689576bd}</Project>
<Project>{353C7A43-D286-4F96-A221-363157CF20BC}</Project>
<Name>Octane.Xamarin.Forms.VideoPlayer</Name>
</ProjectReference>
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,40 @@ public virtual bool CanSeek(int time)
|| player.CurrentItem.CanStepForward);
}

/// <summary>
/// Seeks to a specific position on the playback stream.
/// </summary>
/// <param name="time">The time in milliseconds.</param>
public virtual void SeekTo(int time)
{
if(CanSeekTo(time))
{
var player = _playerControl?.Player;

if (player != null)
{
var currentTime = player.CurrentTime.Seconds;
var timeScale = player.CurrentItem.Duration.TimeScale;
var newTime = time / 1000d;
Log.Info($"SEEK: CurrentTime={currentTime}; TimeScale={timeScale}; NewTime={newTime}");
player.Seek(CMTime.FromSeconds(newTime, timeScale), CMTime.Zero, CMTime.Zero);
}
}
}

/// <summary>
/// Determines if the video player instance can seek to a given position.
/// </summary>
/// <param name="time">The time in milliseconds.</param>
/// <returns></returns>
/// <c>true</c> if this instance can stop; otherwise, <c>false</c>.
public virtual bool CanSeekTo(int time)
{
var player = _playerControl?.Player;
return player != null && (player.CurrentItem.CanStepBackward
|| player.CurrentItem.CanStepForward) && (time >= 0 && time <= (_playerControl.Player.CurrentItem.Duration.Seconds * 1000));
}

#endregion

#region ViewRenderer Overrides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,20 @@ internal interface IVideoPlayerRenderer
/// <c>true</c> if this instance can stop; otherwise, <c>false</c>.
bool CanSeek(int time);

#endregion
}
/// <summary>
/// Seeks to a specific position in milliseconds on the playback stream.
/// </summary>
/// <param name="time">The time in milliseconds .</param>
void SeekTo(int time);

/// <summary>
/// Determines if the video player instance can seek to a given position in milliseconds.
/// </summary>
/// <param name="time">The time in milliseconds.</param>
/// <returns></returns>
/// <c>true</c> if this instance can stop; otherwise, <c>false</c>.
bool CanSeekTo(int time);

#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
<Authors></Authors>
<Company>Octane Software, LLC</Company>
<Product>Xamarin.Forms Video Player</Product>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageId>Octane.Xam.VideoPlayer</PackageId>
<Copyright>Copyright © 2019</Copyright>
<PackageLicenseUrl>https://github.com/adamfisher/Xamarin.Forms.VideoPlayer/blob/master/License.md</PackageLicenseUrl>
<PackageProjectUrl>https://github.com/adamfisher/Xamarin.Forms.VideoPlayer</PackageProjectUrl>
<PackageIconUrl>https://github.com/adamfisher/Xamarin.Forms.VideoPlayer/raw/master/icons/VideoPlayer_128x128.png</PackageIconUrl>
<PackageTags>xamarin forms xamarin.forms ios android windows phone mobile video portable ui AVPlayer MediaPlayer AVPlayerViewController MediaElement pcl xam.pcl wp8 winphone UWP</PackageTags>
<Description>A Xamarin Forms control to render the native video player on every platform.</Description>
<PackOnBuild>true</PackOnBuild>
<ReleaseVersion>0.1.1</ReleaseVersion>
</PropertyGroup>

<PropertyGroup>
Expand Down
35 changes: 34 additions & 1 deletion src/Octane.Xamarin.Forms.VideoPlayer/VideoPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -464,10 +464,29 @@ public ICommand SeekCommand
private set { SetValue(SeekCommandProperty, value); }
}

/// <summary>
/// The seek command property.
/// </summary>
public static readonly BindableProperty SeekToCommandProperty = BindableProperty.Create(nameof(SeekToCommand), typeof(ICommand), typeof(VideoPlayer), null);

/// <summary>
/// This command seeks to a specific position in milliseconds.
/// </summary>
/// <value>
/// The seek to command.
/// </value>
public ICommand SeekToCommand
{
get { return (ICommand)GetValue(SeekToCommandProperty); }
private set { SetValue(SeekToCommandProperty, value); }
}



#endregion

#region Constructors

/// <summary>
/// Initializes a new instance of the <see cref="VideoPlayer"/> class.
/// </summary>
Expand All @@ -488,6 +507,10 @@ public VideoPlayer()
SeekCommand = new Command<string>(
(time) => NativeRenderer?.Seek(int.Parse(time)),
(time) => NativeRenderer != null && NativeRenderer.CanSeek(int.Parse(time)));

SeekToCommand = new Command<string>(
(time) => NativeRenderer?.SeekTo(int.Parse(time)),
(time) => NativeRenderer != null && NativeRenderer.CanSeekTo(int.Parse(time)));
}

/// <summary>
Expand Down Expand Up @@ -547,6 +570,16 @@ public void Seek(int time)
SeekCommand.Execute(time.ToString());
}

/// <summary>
/// Seeks to a specific position in milliseconds in the playback stream.
/// It may be best to hook into the <c>PlayerStateChanged</c> event to listen for the prepared state before calling this method directly.
/// </summary>
/// <param name="time">The time in seconds to seek forward or backward.</param>
public void SeekTo(int time)
{
SeekToCommand.Execute(time.ToString());
}

#endregion
}
}