Skip to content

Commit

Permalink
Merge branch 'release/6.2.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
pyby committed Dec 10, 2021
2 parents fbd7ad3 + b046b6a commit c41bf43
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 18 deletions.
2 changes: 1 addition & 1 deletion Demo/Demo.xcconfig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Version information
MARKETING_VERSION = 6.1.5
MARKETING_VERSION = 6.2.0

// Deployment targets
IPHONEOS_DEPLOYMENT_TARGET = 9.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ - (void)viewDidLoad
self.audioOnlyImageView.image = nil;
self.audioOnlyImageView.image = audioOnlyImage;

self.mediaPlayerController.pictureInPictureEnabled = YES;

SRGMediaPlayerView *playerView = self.mediaPlayerController.view;
playerView.viewMode = self.media.is360 ? SRGMediaPlayerViewModeMonoscopic : SRGMediaPlayerViewModeFlat;

Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import PackageDescription

struct ProjectSettings {
static let marketingVersion: String = "6.1.5"
static let marketingVersion: String = "6.2.0"
}

let package = Package(
Expand Down
4 changes: 2 additions & 2 deletions Sources/SRGMediaPlayer/Resources/it.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"When '%@' is enabled, and if the selected audio track language differs from the device settings, subtitles or Closed Captions might be displayed automatically." = "Quando \"%@\" è attivato, se la pista audio è differente da quella selezionata sul dispositivo, i sottotitoli vengono mostrati automaticamente.";

/* Instructions for subtitles customization */
"You can adjust text appearance and enable Closed Captions and SDH automatic selection in the Accessibility settings." = "Potete regolare la visualizzazione e la sezione automatica dei sottotitoli nelle impostazioni di accessibilità.";
"You can adjust text appearance and enable Closed Captions and SDH automatic selection in the Accessibility settings." = "Puoi regolare la visualizzazione e la sezione automatica dei sottotitoli nelle impostazioni di accessibilità.";

/* Instructions for audio customization */
"You can enable Audio Description automatic selection in the Accessibility settings." = "Potete regolare l'attivazione automatica dell'audio descrizione nelle impostazioni di accessibilità.";
"You can enable Audio Description automatic selection in the Accessibility settings." = "Puoi regolare l'attivazione automatica dell'audio descrizione nelle impostazioni di accessibilità.";
39 changes: 31 additions & 8 deletions Sources/SRGMediaPlayer/SRGMediaPlayerController.m
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ @interface SRGMediaPlayerController () <SRGMediaPlayerViewDelegate, SRGPlayerDel
@property (nonatomic, weak) id<SRGSegment> targetSegment; // Will be nilled when reached
@property (nonatomic) SRGMediaPlayerSelectionReason selectionReason;

@property (nonatomic, getter=isPictureInPictureEnabled) BOOL pictureInPictureEnabled API_AVAILABLE(ios(9.0), tvos(14.0));
@property (nonatomic) AVPictureInPictureController *pictureInPictureController API_AVAILABLE(ios(9.0), tvos(14.0));
@property (nonatomic, copy) void (^pictureInPictureControllerCreationBlock)(AVPictureInPictureController *pictureInPictureController) API_AVAILABLE(ios(9.0), tvos(14.0));
@property (nonatomic) NSNumber *savedAllowsExternalPlayback;
Expand All @@ -128,7 +129,7 @@ @interface SRGMediaPlayerController () <SRGMediaPlayerViewDelegate, SRGPlayerDel
@implementation SRGMediaPlayerController

@synthesize view = _view;

@synthesize pictureInPictureEnabled = _pictureInPictureEnabled;
@synthesize pictureInPictureController = _pictureInPictureController;

#pragma mark Object lifecycle
Expand All @@ -137,6 +138,7 @@ - (instancetype)init
{
if (self = [super init]) {
_playbackState = SRGMediaPlayerPlaybackStateIdle;
_pictureInPictureEnabled = NO;

self.liveTolerance = SRGMediaPlayerDefaultLiveTolerance;
self.endTolerance = SRGMediaPlayerDefaultEndTolerance;
Expand Down Expand Up @@ -761,7 +763,23 @@ - (void)setTextStyleRules:(NSArray<AVTextStyleRule *> *)textStyleRules
self.player.currentItem.textStyleRules = _textStyleRules;
}

- (AVPictureInPictureController *)pictureInPictureController API_AVAILABLE(ios(9.0), tvos(14.0))
- (BOOL)isPictureInPictureEnabled
{
if (self.playerViewController) {
return YES;
}
else {
return _pictureInPictureEnabled;
}
}

- (void)setPictureInPictureEnabled:(BOOL)pictureInPictureEnabled
{
_pictureInPictureEnabled = pictureInPictureEnabled;
[self updatePictureInPictureForView:self.view];
}

- (AVPictureInPictureController *)pictureInPictureController
{
if (self.playerViewController) {
return nil;
Expand All @@ -771,7 +789,7 @@ - (AVPictureInPictureController *)pictureInPictureController API_AVAILABLE(ios(9
}
}

- (void)setPictureInPictureController:(AVPictureInPictureController *)pictureInPictureController API_AVAILABLE(ios(9.0), tvos(14.0))
- (void)setPictureInPictureController:(AVPictureInPictureController *)pictureInPictureController
{
if (_pictureInPictureController) {
[_pictureInPictureController removeObserver:self keyPath:@keypath(_pictureInPictureController.pictureInPicturePossible)];
Expand All @@ -797,13 +815,18 @@ - (void)setPictureInPictureController:(AVPictureInPictureController *)pictureInP

- (void)updatePictureInPictureForView:(SRGMediaPlayerView *)view API_AVAILABLE(ios(9.0), tvos(14.0))
{
AVPlayerLayer *playerLayer = view.playerLayer;
if (playerLayer.readyForDisplay) {
if (self.pictureInPictureController.playerLayer != playerLayer) {
self.pictureInPictureController = [[AVPictureInPictureController alloc] initWithPlayerLayer:playerLayer];
self.pictureInPictureControllerCreationBlock ? self.pictureInPictureControllerCreationBlock(self.pictureInPictureController) : nil;
if (! self.playerViewController && self.pictureInPictureEnabled) {
AVPlayerLayer *playerLayer = view.playerLayer;
if (playerLayer.readyForDisplay) {
if (self.pictureInPictureController.playerLayer != playerLayer) {
self.pictureInPictureController = [[AVPictureInPictureController alloc] initWithPlayerLayer:playerLayer];
self.pictureInPictureControllerCreationBlock ? self.pictureInPictureControllerCreationBlock(self.pictureInPictureController) : nil;
}
}
}
else {
self.pictureInPictureController = nil;
}
}

- (BOOL)allowsExternalNonMirroredPlayback
Expand Down
13 changes: 12 additions & 1 deletion Sources/SRGMediaPlayer/include/SRGMediaPlayerController.h
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,10 @@ NS_ASSUME_NONNULL_BEGIN
@end

/**
* Picture in picture functionality (not available on all devices).
* Picture in picture functionality (not available on all devices). Picture in picture is an opt-in: You must set the
* controller `pictureInPictureEnabled` property to `YES` if you want it to support picture in picture. You should also
* implement a picture in picture controller delegate to manage the picture in picture lifecycle (you can register
* a delegate with a blocked assigned to `pictureInPictureControllerCreationBlock`).
*
* Remark: When the application is sent to the background on iOS, the behavior is the same as the vanilla picture in picture
* controller: If the managed player layer is the one of a view controller's root view ('full screen'), picture
Expand All @@ -870,6 +873,14 @@ NS_ASSUME_NONNULL_BEGIN
*/
@interface SRGMediaPlayerController (PictureInPicture)

/**
* Set to `YES` to activate picture in picture for the controller. Default is `NO`.
*
* @discussion Setting this property has no effect when the controller is used by `SRGMediaPlayerViewController`, as
* picture in picture is always enabled in this special case.
*/
@property (nonatomic, getter=isPictureInPictureEnabled) BOOL pictureInPictureEnabled API_AVAILABLE(ios(9.0), tvos(14.0));

/**
* Return the picture in picture controller if picture in picture is available for the device, `nil` otherwise.
*
Expand Down
2 changes: 2 additions & 0 deletions Sources/SRGMediaPlayer/include/SRGMediaPlayerViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ NS_ASSUME_NONNULL_BEGIN
* standard Apple player user experience, at the expense of a few limitations:
* - 360° medias are not playable with monoscopic or stereoscopic support.
* - Background playback behavior cannot be customized.
* - Picture in picture is always enabled (but still requires you to implement its controller delegate methods to
* manage the picture in picture lifecycle).
*
* If you need one of the above features you should implement your own player layout instead.
*/
Expand Down
14 changes: 9 additions & 5 deletions docs/GETTING_STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,7 @@ SRGMediaPlayerViewController *mediaPlayerViewController = [[SRGMediaPlayerViewCo
}];
```
Please refer to `AVPlayerViewController` [documentation](https://developer.apple.com/documentation/avkit/avpictureinpicturecontroller) for further integration instructions, from picture in picture to optional settings.
### Remark
Picture in picture requires your application to declare the corresponding background mode capability, as well as an audio session category set to `AVAudioSessionCategoryPlayback`.
Please refer to `AVPlayerViewController` [documentation](https://developer.apple.com/documentation/avkit/avpictureinpicturecontroller) for further integration instructions, from picture in picture support to optional settings.
## Designing custom players
Expand Down Expand Up @@ -110,6 +106,14 @@ You can also drop an `SRGAirPlayButton` onto your layout (displayed only when Ai
If you want users to reliably enable AirPlay playback also from the control center, you should use `SRGAirPlayButton` with your player layout, or integrate `MPRemoteCommandCenter`. These ensures your application is the current one registered with the control center when the user interacts with it, so that playback can actually be sent to an AirPlay receiver. If your application is not the current one at the moment the route is changed in the control center, playback will stay local.
## Picture in picture support
SRG Media Player supports picture in picture, both on iOS and on tvOS. You must opt-in for picture in picture by setting the `pictureInPictureEnabled` property to `YES` on an `SRGMediaPlayerController` instance. Picture in picture also requires your application to declare the corresponding background mode capability, as well as an audio session category set to `AVAudioSessionCategoryPlayback`.
When picture in picture has been enabled your application is responsible of implementing the `AVPictureInPictureControllerDelegate` methods to manage the picture in picture lifecycle, in particular the restoration process. You can register your delegate within a block assigned to the `pictureInPictureControllerCreationBlock` property, which is called after a picture in picture controller has been made available.
Note that, if you are using `SRGMediaPlayerViewController` to display the standard system player user interface, the underlying `SRGMediaPlayerController` will always have picture in picture enabled. To ensure correct integration your application must provide a `SRGMediaPlayerViewControllerDelegate` implementing picture in picture lifecycle, most notably for restoration.
## Audio session management
No audio session specific management is provided by the library. Managing audio sessions is entirely the responsibility of the application, which gives you complete freedom over how playback happens, especially in the background or when switching between applications. As for AirPlay setup (see above), you can use the various block hooks to setup and restore audio session settings as required by your application.
Expand Down

0 comments on commit c41bf43

Please sign in to comment.