Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6d89524

Browse files
added new Event boundsChanged
1 parent 9b7acdd commit 6d89524

File tree

7 files changed

+56
-3
lines changed

7 files changed

+56
-3
lines changed

‎README.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ In cases where you need to re-issue a command that might appear redundant but is
189189
|----------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
190190
| `addVector(ShapeLayerBuilderProtocol, clear: Bool)` | Command to add a vector graphic layer over the video stream. The `builder` parameter is an instance conforming to `ShapeLayerBuilderProtocol`. The `clear` parameter specifies whether to clear existing vector layers before adding the new one. |
191191
| `removeAllVectors` | Command to remove all vector graphic layers from the video stream. |
192+
### Additional Notes on the subtitles Command
193+
The boundsChanged event(`boundsChanged(CGRect)`) is triggered when the main layer’s bounds are updated. This approach is particularly useful when overlays or custom vector layers need to adapt dynamically to changes in video player dimensions or other layout adjustments. To handle the frequent boundsChanged events effectively and improve performance, you can use a **throttle** function to limit how often the updates occur.
192194

193195
### Audio & Language Commands
194196

@@ -235,6 +237,7 @@ video_main.m3u8
235237
| `currentItemRemoved` | Occurs when the player's `currentItem` is set to `nil`, indicating that the current media item has been removed from the player. |
236238
| `error(VPErrors)` | Represents an occurrence of an error within the player. The event provides a `VPErrors` enum value indicating the specific type of error encountered. |
237239
| `volumeChanged` | Happens when the player's volume level is adjusted. This event provides the new volume level, which ranges from 0.0 (muted) to 1.0 (maximum volume). |
240+
| `boundsChanged(CGRect)` | Triggered when the bounds of the main layer change, allowing the developer to recalculate and update all vector layers within the CompositeLayer. |
238241

239242

240243
### Additional Notes on Adding and Removing Vector Graphics

‎Sources/swiftui-loop-videoplayer/enum/PlayerEvent.swift‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ public enum PlayerEvent: Equatable {
5959
///
6060
/// - Parameter VPErrors: The error from the VPErrors enum associated with this case.
6161
case error(VPErrors)
62+
63+
64+
case boundsChanged(CGRect)
6265
}
6366

6467
extension PlayerEvent: CustomStringConvertible {
@@ -80,6 +83,8 @@ extension PlayerEvent: CustomStringConvertible {
8083
return "VolumeChanged"
8184
case .error(let e):
8285
return "\(e.description)"
86+
case .boundsChanged(let bounds):
87+
return "Bounds changed \(bounds)"
8388
}
8489
}
8590
}

‎Sources/swiftui-loop-videoplayer/protocol/helpers/PlayerDelegateProtocol.swift‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,9 @@ public protocol PlayerDelegateProtocol: AnyObject {
6464
/// - Parameter newVolume: The new volume level, expressed as a float between 0.0 (muted) and 1.0 (maximum volume).
6565
func volumeDidChange(to newVolume: Float)
6666

67+
/// Notifies that the bounds have changed.
68+
///
69+
/// - Parameter bounds: The new bounds of the main layer where we keep the video player and all vector layers. This allows a developer to recalculate and update all vector layers that lie in the CompositeLayer.
70+
71+
func boundsDidChange(to bounds: CGRect)
6772
}

‎Sources/swiftui-loop-videoplayer/protocol/vector/ShapeLayerBuilderProtocol.swift‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,4 @@ public protocol ShapeLayerBuilderProtocol: Identifiable {
2828
/// - Returns: A configured `CAShapeLayer`.
2929
@MainActor
3030
func build(with geometry: (frame: CGRect, bounds: CGRect)) -> CAShapeLayer
31-
3231
}

‎Sources/swiftui-loop-videoplayer/view/helpers/PlayerCoordinator.swift‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,12 @@ internal class PlayerCoordinator: NSObject, PlayerDelegateProtocol {
111111
func volumeDidChange(to newVolume: Float){
112112
eventPublisher.send(.volumeChanged(newVolume: newVolume))
113113
}
114+
115+
/// Notifies that the bounds have changed.
116+
///
117+
/// - Parameter bounds: The new bounds of the main layer where we keep the video player and all vector layers. This allows a developer to recalculate and update all vector layers that lie in the CompositeLayer.
118+
119+
func boundsDidChange(to bounds: CGRect) {
120+
eventPublisher.send(.boundsChanged(bounds))
121+
}
114122
}

‎Sources/swiftui-loop-videoplayer/view/player/ios/ExtPlayerUIView.swift‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,23 @@ internal class ExtPlayerUIView: UIView, ExtPlayerProtocol {
8989
override func layoutSubviews() {
9090
super.layoutSubviews()
9191
playerLayer?.frame = bounds
92-
compositeLayer?.frame = bounds
92+
// Update the composite layer (and sublayers)
93+
layoutCompositeLayer()
94+
}
95+
96+
/// Updates the composite layer and all its sublayers' frames.
97+
public func layoutCompositeLayer() {
98+
guard let compositeLayer = compositeLayer else { return }
99+
100+
// Update the composite layer's frame to match the parent
101+
compositeLayer.frame = bounds
102+
103+
// Adjust each sublayer's frame (if they should fill the entire composite layer)
104+
compositeLayer.sublayers?.forEach { sublayer in
105+
sublayer.frame = compositeLayer.bounds
106+
}
107+
108+
delegate?.boundsDidChange(to: bounds)
93109
}
94110

95111
func onDisappear(){

‎Sources/swiftui-loop-videoplayer/view/player/mac/ExtPlayerNSView.swift‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import AppKit
1616

1717
/// A NSView subclass that loops video using AVFoundation on macOS.
1818
/// This class handles the initialization and management of a looping video player with customizable video gravity.
19+
@MainActor
1920
internal class ExtPlayerNSView: NSView, ExtPlayerProtocol {
2021

2122
/// This property holds an instance of `VideoSettings`
@@ -88,7 +89,23 @@ internal class ExtPlayerNSView: NSView, ExtPlayerProtocol {
8889
override func layout() {
8990
super.layout()
9091
playerLayer?.frame = bounds
91-
compositeLayer?.frame = bounds
92+
// Update the composite layer (and sublayers)
93+
layoutCompositeLayer()
94+
}
95+
96+
/// Updates the composite layer and all its sublayers' frames.
97+
public func layoutCompositeLayer() {
98+
guard let compositeLayer = compositeLayer else { return }
99+
100+
// Update the composite layer's frame to match the parent
101+
compositeLayer.frame = bounds
102+
103+
// Adjust each sublayer's frame (if they should fill the entire composite layer)
104+
compositeLayer.sublayers?.forEach { sublayer in
105+
sublayer.frame = compositeLayer.bounds
106+
}
107+
108+
delegate?.boundsDidChange(to: bounds)
92109
}
93110

94111

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /