PlayerControls is a macOS Cocoa framework that creates a View containing playback controls for media like videos or sounds. It is written in pure Swift 4 and has no dependencies.
Primarily, this is written to work with
VLCKit which provides a media player
playback mechanism with no controls. But it does not rely on
VLCKit and is
suitably generic to be useful in many situations.
- Extends NSVisualEffectView for a nice blurred effect when overlaying a video.
- Eminently customizable. Almost all controls can be hidden and icons customized.
- Implements a simple delegate protocol to respond to events.
- AutoLayout aware, responds nicely to resizing.
- Provides theme support. A Light and Dark theme are included, and creating your own is trivial.
Add to your
Alternatively, download the source, build the framework and drag the product into your project.
A demonstration app is available in the source code. To use it, download the source, open in Xcode, set the Scheme to PlayerControlsDemo and build. It will build the framework as a dependency.
Import the framework.
In your Storyboard file, create an
NSView (Custom View) instance and set it's
PlayerControl. This will create your PlayerControl instance.
Natively it doesn't look like much. You'll need to provide some customizations.
To programatically use
PlayerControl, you can do this:
let playerControl = PlayerControl()
You can customize the following properties on the
PlayerControl class to
change it's behavior or appearance.
The following two properties are required and not setting them will basically cause the control to be non-functional.
public var totalTime: TimeInterval? = nil
The total length of the media you are playing.
public var currentTime: TimeInterval = 0
The current playback time. This starts out as zero and should be updated by your
calling code. When you are using
VLCKit, this should be updated from your
mediaPlayerTimeChanged function. This will also be
updated by the control itself (when the user does something to change the
current time), and a callback will be called (see "Responding to Events" below.)
public var delegate: PlayerControlDelegate? = nil
Sets the delegate. See "Responding to Events" below. This is technically optional, but not implementing it doesn't make a lot of sense. :)
@IBInspectable public var jumpForwardTimeInternal: TimeInterval = 15
How far ahead will pushing the Jump Ahead button advance the time. If pushing the button would advance the time beyond the end of the media, the time is set at the end of the media.
@IBInspectable public var jumpBackwardTimeInterval: TimeInterval = 15
How far back will pushing the Jump Backward button reduce the time. If pushing the button would reduce the time beyond the beginning of the media, the time is set at 0.
public var transferred: CGFloat = 0
If you are using the downloading display to show how much of a streaming file has transferred, updating this will cause that to be displayed in the slider. This is a float between 0.0 and 1.0 representing the percentage of the file transferred.
@IBInspectable public var hideOnMouseOut: Bool = true
If you want the display to hide when the mouse exits the view. The mouse re- entering the bounds of the view will cause it to become visible again.
public var hideAfter: TimeInterval = 5
The view is initially visible. If
hideOnMouseOut is true, this is how long the
view will remain visible before being hidden.
public var hiddenAlphaValue: CGFloat = 0
Sets the alpha value when the control is hidden.
public var visibleAlphaValue: CGFloat = 1
Sets the alpha value when the control is visible.
public var status: Status = .paused
Sets the current status of the PlayerControl. Options are
.paused. This should be updated from your controller if something changes. If
you are using
VLCKit, it should be updated from the
delegate method. This will also be updated by the control reflecting changes by
the user. This will trigger a delegate method call.
public var theme: PlayerControlTheme = Dark()
The theme to use.
Dark is the default, but
Light is also available. See the
section on Themes below.
@IBInspectable public var iconSize = NSSize(width: 100, height: 100)
The size of icons to use. This should be set to the largest possible size that will be used on your play/pause button. It will be automatically scaled down for your smaller buttons.
@IBInspectable public var showRewindButton: Bool = true
Whether the Rewind button is visible.
@IBInspectable public var showFastForwardButton: Bool = true
Whether the Fast Forward button is visible.
@IBInspectable public var showJumpBackButton: Bool = true
Whether the Jump Back button is visible.
@IBInspectable public var showForwardButton: Bool = true
Whether the Jump Forward button is visible.
@IBInspectable public var showLabels: Bool = true
Whether the time labels are visible.
@IBInspectable public var rewindbuttonImage: NSImage?
The image used on the Rewind button.
@IBInspectable public var fastForwardButtonImage: NSImage?
The image used on the Fast Forward button.
@IBInspectable public var jumpBackButtonImage: NSImage?
The image used on the Jump Back button.
@IBInspectable public var jumpForwardButtonImage: NSImage?
The image used on the Jump Forward button.
@IBInspectable public var playButtonImage: NSImage?
The image used on the Play button.
@IBInspectable public var pauseButtonImage: NSImage?
The image used on the Pause button. From a technical standpoint, Play and Pause are the same button, and the image is swapped depending on the state.
PlayerControl supports themes that can control some parts of the appearance
of the control. Two themes are included,
Dark is the
default. You can create your own themes by creating a class or struct that
PlayerControlTheme protocol, then setting the
PlayerControl class to an instance of your theme.
You can customize the following variables:
public var blendingMode: NSVisualEffectView.BlendingMode
Sets the underlying view's blending mode.
public var material: NSVisualEffectView.Material
Sets the underlying view's material.
public var buttonColor: NSColor
The background color used on buttons.
public var buttonAlpha: CGFloat
The alpha transparency used on buttons.
public var labelTextColor: NSColor
The text color on time labels.
public var sliderKnobColor: NSColor
The color of the slider knob (line).
public var sliderBarColor: NSColor
The color of the slider bar.
public var sliderBarDownloadColor: NSColor
The color of the part of the bar representing the download percentage.
public var sliderBarAlpha: CGFloat
The alpha transparency of the bar.
Responding to Events
To respond to PlayerControl events, you can implement the
PlayerControlDelegate in your controller. This will provide you with the
following callback events:
func statusChanged(_ playerControl: PlayerControl, status: PlayerControl.Status)
Called when the status of the player changes. You are passed back an instance of
PlayerControl and the status, which is one of
.paused. This is called after the user pressed play or pause.
func timeChanged(_ playerControl: PlayerControl, time: TimeInterval)
Called when the controls change the current time of playback. This can be called
by a number of actions, including sliding the slider, or using the playback
buttons like jump ahead/back, or fast forward or rewind. The
the new time interval.
Don't forget to set your class as the delegate.