This repository provides an F# WebSharper binding for the Picture-in-Picture API, enabling seamless integration of Picture-in-Picture (PiP) functionality into WebSharper applications.
The repository consists of two main projects:
-
Binding Project:
- Contains the F# WebSharper binding for the Picture-in-Picture API.
-
Sample Project:
- Demonstrates how to use the Picture-in-Picture API with WebSharper syntax.
- Includes a GitHub Pages demo: View Demo
To use this package in your WebSharper project, add the NuGet package:
dotnet add package WebSharper.PictureInPicture
- .NET SDK installed on your machine.
-
Clone the repository:
git clone https://github.com/dotnet-websharper/PictureInPictureAPI.git cd PictureInPictureAPI
-
Build the Binding Project:
dotnet build WebSharper.PictureInPicture/WebSharper.PictureInPicture.fsproj
-
Build and Run the Sample Project:
cd WebSharper.PictureInPicture.Sample dotnet build dotnet run
-
Open the sample project in your browser to see it in action.
Below is an example of how to use the Picture-in-Picture API in a WebSharper project:
namespace WebSharper.PictureInPicture.Sample
open WebSharper
open WebSharper.JavaScript
open WebSharper.UI
open WebSharper.UI.Client
open WebSharper.UI.Templating
open WebSharper.PictureInPicture
[<JavaScript>]
module Client =
// The templates are loaded from the DOM, so you just can edit index.html
// and refresh your browser, no need to recompile unless you add or remove holes.
type IndexTemplate = Template<"wwwroot/index.html", ClientLoad.FromDocument>
// Get references to the video element and PiP toggle button
let video = JS.Document.GetElementById("video") |> As<HTMLVideoElement>
let pipButton = JS.Document.GetElementById("pipButton") |> As<HTMLButtonElement>
// Function to toggle Picture-in-Picture mode
let togglePiPMode () =
promise {
try
let doc = JS.Document
if Optional.isUndefined doc.PictureInPictureElement then
// Exit Picture-in-Picture mode if it's already active
do! doc.ExitPictureInPicture()
else
// Request to enter Picture-in-Picture mode
video.RequestPictureInPicture() |> ignore
with error ->
Console.Error($"Error toggling Picture-in-Picture mode: {error}")
}
// Set up event listeners to update button text when PiP mode changes
let setupPiPEvents () =
video.AddEventListener("enterpictureinpicture", fun (_: Dom.Event) ->
pipButton.InnerText <- "Exit PiP Mode"
)
video.AddEventListener("leavepictureinpicture", fun (_: Dom.Event) ->
pipButton.InnerText <- "Toggle PiP Mode"
)
[<SPAEntryPoint>]
let Main () =
IndexTemplate.Main()
.PageInit(fun () ->
setupPiPEvents()
pipButton.AddEventListener("click", fun (_: Dom.Event) ->
async {
do! togglePiPMode() |> Promise.AsAsync
} |> Async.StartImmediate
)
)
.Doc()
|> Doc.RunById "main"
This example demonstrates how to toggle Picture-in-Picture mode for a video element, handling user interaction and updating UI elements accordingly.
- Browser Support: The Picture-in-Picture API is not supported on all browsers. Check the MDN Picture-in-Picture API for compatibility details.
- User Gesture Requirement: Some browsers require user interaction (e.g., a button click) before allowing Picture-in-Picture mode.
- Limitations: Only one video can be in Picture-in-Picture mode at a time.