Skip to content

Commit

Permalink
Feature/october changes (jhomlala#763)
Browse files Browse the repository at this point in the history
* Fixed full screen safe area issue in cupertino controls

* Changed min. Flutter version to 2.2.3.

* Fixed subtitles duplication after changing data source.

* Added url parameter for changedResolution event

* Updated license

* Added [videoExtension] support for network data source for scenario where video source has no extension and cache manager requires it.

* Fixed progress bar issues when changing position of the video

* Added parameters to changedTrack event

* Added [changedPlaylistItem] event.

* auto detect fullscreen aspect ratio (jhomlala#741)

* Updated changelog, updated doc

* Updated docs

* Updated formatting

* Changed log level in ExoPlayer to Error.

* Updated screenshots

* Updated documentation

Co-authored-by: Maciej Brażewicz <brazol@gmail.com>
  • Loading branch information
jhomlala and Brazol authored Oct 16, 2021
1 parent 6186d18 commit 9ad3e88
Show file tree
Hide file tree
Showing 60 changed files with 379 additions and 301 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
## 0.0.77
* Fixed full screen safe area issue in cupertino controls.
* Fixed subtitles duplication after changing data source.
* Fixed progress bar issues when changing position of the video.
* [BREAKING_CHANGE] Changed min. Flutter version to 2.2.3.
* Changed log level in ExoPlayer to Error.
* Added url parameter for changedResolution event.
* Added [videoExtension] support for network data source for scenario where video source has no extension and cache manager requires it.
* Added parameters to [changedTrack] event.
* Added [changedPlaylistItem] event.
* Added [autoDetectFullscreenAspectRatio] parameter in [BetterPlayerConfiguration] (by https://github.com/Brazol)
* Updated license.
* Updated screenshots.

## 0.0.76
* Fixed iOS build issue.
* [BREAKING_CHANGE] Changed min required iOS version to 11.
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]
Copyright 2020 Jakub Homlala and Better Player / Chewie / Video Player contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
1 change: 1 addition & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ linter:
invalid_dependency: false
sort_pub_dependencies: false
avoid_unnecessary_containers: false
use_setters_to_change_properties: false

Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ final class BetterPlayer {
TextureRegistry.SurfaceTextureEntry textureEntry,
CustomDefaultLoadControl customDefaultLoadControl,
Result result) {
com.google.android.exoplayer2.util.Log.setLogLevel(
com.google.android.exoplayer2.util.Log.LOG_LEVEL_ERROR);
this.eventChannel = eventChannel;
this.textureEntry = textureEntry;
trackSelector = new DefaultTrackSelector(context);
Expand Down Expand Up @@ -568,7 +570,7 @@ public void onCancel(Object o) {
exoPlayer.addListener(new Player.Listener() {
@Override
public void onPlaybackStateChanged(int playbackState) {

if (playbackState == Player.STATE_BUFFERING) {
sendBufferingUpdate(true);
Map<String, Object> event = new HashMap<>();
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion docs/_coverpage.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
- Supports both Android and iOS

[GitHub](https://github.com/jhomlala/betterplayer)
[Get Started](#README)
[Get Started](https://jhomlala.github.io/betterplayer/#/README)
9 changes: 8 additions & 1 deletion docs/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ You can listen to video player events like:
changedSubtitles,
changedTrack,
changedPlayerVisibility,
changedResolution
changedResolution,
pipStart,
pipStop,
setupDataSource,
bufferingStart,
bufferingUpdate,
bufferingEnd,
changedPlaylistItem
```

After creating `BetterPlayerController` you can add event listener this way:
Expand Down
4 changes: 4 additions & 0 deletions docs/generalconfiguration.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ final List<BetterPlayerTranslations> translations;
/// ignored.
final bool autoDetectFullscreenDeviceOrientation;
///Defines if player should auto detect full screen aspect ration of the video.
///If [deviceOrientationsOnFullScreen] is true this is done automaticaly also.
final bool autoDetectFullscreenAspectRatio;
///Defines flag which enables/disables lifecycle handling (pause on app closed,
///play on app resumed). Default value is true.
final bool handleLifecycle;
Expand Down
Empty file removed flutter_01.png
Empty file.
Binary file removed flutter_02.png
Binary file not shown.
2 changes: 1 addition & 1 deletion ios/Classes/BetterPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)setMixWithOthers:(bool)mixWithOthers;
- (void)seekTo:(int)location;
- (void)setDataSourceAsset:(NSString*)asset withKey:(NSString*)key withCertificateUrl:(NSString*)certificateUrl withLicenseUrl:(NSString*)licenseUrl cacheKey:(NSString*)cacheKey cacheManager:(CacheManager*)cacheManager overriddenDuration:(int) overriddenDuration;
- (void)setDataSourceURL:(NSURL*)url withKey:(NSString*)key withCertificateUrl:(NSString*)certificateUrl withLicenseUrl:(NSString*)licenseUrl withHeaders:(NSDictionary*)headers withCache:(BOOL)useCache cacheKey:(NSString*)cacheKey cacheManager:(CacheManager*)cacheManager overriddenDuration:(int) overriddenDuration;
- (void)setDataSourceURL:(NSURL*)url withKey:(NSString*)key withCertificateUrl:(NSString*)certificateUrl withLicenseUrl:(NSString*)licenseUrl withHeaders:(NSDictionary*)headers withCache:(BOOL)useCache cacheKey:(NSString*)cacheKey cacheManager:(CacheManager*)cacheManager overriddenDuration:(int) overriddenDuration videoExtension: (NSString*) videoExtension;
- (void)setVolume:(double)volume;
- (void)setSpeed:(double)speed result:(FlutterResult)result;
- (void) setAudioTrack:(NSString*) name index:(int) index;
Expand Down
10 changes: 7 additions & 3 deletions ios/Classes/BetterPlayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,10 @@ - (CGAffineTransform)fixTransform:(AVAssetTrack*)videoTrack {

- (void)setDataSourceAsset:(NSString*)asset withKey:(NSString*)key withCertificateUrl:(NSString*)certificateUrl withLicenseUrl:(NSString*)licenseUrl cacheKey:(NSString*)cacheKey cacheManager:(CacheManager*)cacheManager overriddenDuration:(int) overriddenDuration{
NSString* path = [[NSBundle mainBundle] pathForResource:asset ofType:nil];
return [self setDataSourceURL:[NSURL fileURLWithPath:path] withKey:key withCertificateUrl:certificateUrl withLicenseUrl:(NSString*)licenseUrl withHeaders: @{} withCache: false cacheKey:cacheKey cacheManager:cacheManager overriddenDuration:overriddenDuration];
return [self setDataSourceURL:[NSURL fileURLWithPath:path] withKey:key withCertificateUrl:certificateUrl withLicenseUrl:(NSString*)licenseUrl withHeaders: @{} withCache: false cacheKey:cacheKey cacheManager:cacheManager overriddenDuration:overriddenDuration videoExtension: nil];
}

- (void)setDataSourceURL:(NSURL*)url withKey:(NSString*)key withCertificateUrl:(NSString*)certificateUrl withLicenseUrl:(NSString*)licenseUrl withHeaders:(NSDictionary*)headers withCache:(BOOL)useCache cacheKey:(NSString*)cacheKey cacheManager:(CacheManager*)cacheManager overriddenDuration:(int) overriddenDuration{
- (void)setDataSourceURL:(NSURL*)url withKey:(NSString*)key withCertificateUrl:(NSString*)certificateUrl withLicenseUrl:(NSString*)licenseUrl withHeaders:(NSDictionary*)headers withCache:(BOOL)useCache cacheKey:(NSString*)cacheKey cacheManager:(CacheManager*)cacheManager overriddenDuration:(int) overriddenDuration videoExtension: (NSString*) videoExtension{
_overriddenDuration = 0;
if (headers == [NSNull null] || headers == NULL){
headers = @{};
Expand All @@ -206,7 +206,11 @@ - (void)setDataSourceURL:(NSURL*)url withKey:(NSString*)key withCertificateUrl:(
if (cacheKey == [NSNull null]){
cacheKey = nil;
}
item = [cacheManager getCachingPlayerItemForNormalPlayback:url cacheKey:cacheKey headers:headers];
if (videoExtension == [NSNull null]){
videoExtension = nil;
}

item = [cacheManager getCachingPlayerItemForNormalPlayback:url cacheKey:cacheKey videoExtension: videoExtension headers:headers];
} else {
AVURLAsset* asset = [AVURLAsset URLAssetWithURL:url
options:@{@"AVURLAssetHTTPHeaderFieldsKey" : headers}];
Expand Down
16 changes: 12 additions & 4 deletions ios/Classes/BetterPlayerPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
NSDictionary* headers = dataSource[@"headers"];
NSString* cacheKey = dataSource[@"cacheKey"];
NSNumber* maxCacheSize = dataSource[@"maxCacheSize"];
NSString* videoExtension = dataSource[@"videoExtension"];

int overriddenDuration = 0;
if ([dataSource objectForKey:@"overriddenDuration"] != [NSNull null]){
overriddenDuration = [dataSource[@"overriddenDuration"] intValue];
Expand Down Expand Up @@ -337,7 +339,7 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
}
[player setDataSourceAsset:assetPath withKey:key withCertificateUrl:certificateUrl withLicenseUrl: licenseUrl cacheKey:cacheKey cacheManager:_cacheManager overriddenDuration:overriddenDuration];
} else if (uriArg) {
[player setDataSourceURL:[NSURL URLWithString:uriArg] withKey:key withCertificateUrl:certificateUrl withLicenseUrl: licenseUrl withHeaders:headers withCache: useCache cacheKey:cacheKey cacheManager:_cacheManager overriddenDuration:overriddenDuration];
[player setDataSourceURL:[NSURL URLWithString:uriArg] withKey:key withCertificateUrl:certificateUrl withLicenseUrl: licenseUrl withHeaders:headers withCache: useCache cacheKey:cacheKey cacheManager:_cacheManager overriddenDuration:overriddenDuration videoExtension: videoExtension];
} else {
result(FlutterMethodNotImplemented);
}
Expand Down Expand Up @@ -426,15 +428,20 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
NSString* cacheKey = dataSource[@"cacheKey"];
NSDictionary* headers = dataSource[@"headers"];
NSNumber* maxCacheSize = dataSource[@"maxCacheSize"];
NSString* videoExtension = dataSource[@"videoExtension"];

if (headers == [ NSNull null ]){
headers = @{};
}
if (videoExtension == [NSNull null]){
videoExtension = nil;
}

if (urlArg != [NSNull null]){
NSURL* url = [NSURL URLWithString:urlArg];
if ([_cacheManager isPreCacheSupportedWithUrl:url]){
if ([_cacheManager isPreCacheSupportedWithUrl:url videoExtension:videoExtension]){
[_cacheManager setMaxCacheSize:maxCacheSize];
[_cacheManager preCacheURL:url cacheKey:cacheKey withHeaders:headers completionHandler:^(BOOL success){
[_cacheManager preCacheURL:url cacheKey:cacheKey videoExtension:videoExtension withHeaders:headers completionHandler:^(BOOL success){
}];
} else {
NSLog(@"Pre cache is not supported for given data source.");
Expand All @@ -447,9 +454,10 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
} else if ([@"stopPreCache" isEqualToString:call.method]){
NSString* urlArg = argsMap[@"url"];
NSString* cacheKey = argsMap[@"cacheKey"];
NSString* videoExtension = argsMap[@"videoExtension"];
if (urlArg != [NSNull null]){
NSURL* url = [NSURL URLWithString:urlArg];
if ([_cacheManager isPreCacheSupportedWithUrl:url]){
if ([_cacheManager isPreCacheSupportedWithUrl:url videoExtension:videoExtension]){
[_cacheManager stopPreCache:url cacheKey:cacheKey
completionHandler:^(BOOL success){
}];
Expand Down
25 changes: 14 additions & 11 deletions ios/Classes/CacheManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ import PINCache
}

// MARK: - Logic
@objc public func preCacheURL(_ url: URL, cacheKey: String?, withHeaders headers: Dictionary<NSObject,AnyObject>, completionHandler: ((_ success:Bool) -> Void)?) {
@objc public func preCacheURL(_ url: URL, cacheKey: String?, videoExtension: String?, withHeaders headers: Dictionary<NSObject,AnyObject>, completionHandler: ((_ success:Bool) -> Void)?) {
self.completionHandler = completionHandler

let _key: String = cacheKey ?? url.absoluteString
// Make sure the item is not already being downloaded
if self._preCachedURLs[_key] == nil {
if let item = self.getCachingPlayerItem(url, cacheKey: _key, headers: headers){
if let item = self.getCachingPlayerItem(url, cacheKey: _key, videoExtension: videoExtension, headers: headers){
if !self._existsInStorage {
self._preCachedURLs[_key] = item
item.download()
Expand Down Expand Up @@ -87,20 +87,20 @@ import PINCache
}

///Gets caching player item for normal playback.
@objc public func getCachingPlayerItemForNormalPlayback(_ url: URL, cacheKey: String?, headers: Dictionary<NSObject,AnyObject>) -> AVPlayerItem? {
let mimeTypeResult = getMimeType(url:url)
@objc public func getCachingPlayerItemForNormalPlayback(_ url: URL, cacheKey: String?, videoExtension: String?, headers: Dictionary<NSObject,AnyObject>) -> AVPlayerItem? {
let mimeTypeResult = getMimeType(url:url, explicitVideoExtension: videoExtension)
if (mimeTypeResult.1 == "application/vnd.apple.mpegurl"){
let reverseProxyURL = server?.reverseProxyURL(from: url)!
let playerItem = AVPlayerItem(url: reverseProxyURL!)
return playerItem
} else {
return getCachingPlayerItem(url, cacheKey: cacheKey, headers: headers)
return getCachingPlayerItem(url, cacheKey: cacheKey, videoExtension: videoExtension, headers: headers)
}
}


// Get a CachingPlayerItem either from the network if it's not cached or from the cache.
@objc public func getCachingPlayerItem(_ url: URL, cacheKey: String?, headers: Dictionary<NSObject,AnyObject>) -> CachingPlayerItem? {
@objc public func getCachingPlayerItem(_ url: URL, cacheKey: String?,videoExtension: String?, headers: Dictionary<NSObject,AnyObject>) -> CachingPlayerItem? {
let playerItem: CachingPlayerItem
let _key: String = cacheKey ?? url.absoluteString
// Fetch ongoing pre-cached url if it exists
Expand All @@ -113,7 +113,7 @@ import PINCache
if data != nil {
// The file is cached.
self._existsInStorage = true
let mimeTypeResult = getMimeType(url:url)
let mimeTypeResult = getMimeType(url:url, explicitVideoExtension: videoExtension)
if (mimeTypeResult.1.isEmpty){
NSLog("Cache error: couldn't find mime type for url: \(url.absoluteURL). For this URL cache didn't work and video will be played without cache.")
playerItem = CachingPlayerItem(url: url, cacheKey: _key, headers: headers)
Expand All @@ -136,8 +136,11 @@ import PINCache
self._preCachedURLs = Dictionary<String,CachingPlayerItem>()
}

private func getMimeType(url: URL) -> (String,String){
let videoExtension = url.pathExtension
private func getMimeType(url: URL, explicitVideoExtension: String?) -> (String,String){
var videoExtension = url.pathExtension
if (explicitVideoExtension != nil){
videoExtension = explicitVideoExtension!
}
var mimeType = ""
switch (videoExtension){
case "m3u":
Expand Down Expand Up @@ -194,8 +197,8 @@ import PINCache
}

///Checks wheter pre cache is supported for given url.
@objc public func isPreCacheSupported(url: URL) -> Bool{
let mimeTypeResult = getMimeType(url:url)
@objc public func isPreCacheSupported(url: URL, videoExtension: String?) -> Bool{
let mimeTypeResult = getMimeType(url:url, explicitVideoExtension: videoExtension)
return !mimeTypeResult.1.isEmpty && mimeTypeResult.1 != "application/vnd.apple.mpegurl"
}
}
Expand Down
11 changes: 9 additions & 2 deletions lib/src/asms/better_player_asms_track.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,15 @@ class BetterPlayerAsmsTrack {
///mimeType of the video track
final String? mimeType;

BetterPlayerAsmsTrack(this.id, this.width, this.height, this.bitrate,
this.frameRate, this.codecs, this.mimeType);
BetterPlayerAsmsTrack(
this.id,
this.width,
this.height,
this.bitrate,
this.frameRate,
this.codecs,
this.mimeType,
);

factory BetterPlayerAsmsTrack.defaultTrack() {
return BetterPlayerAsmsTrack('', 0, 0, 0, 0, '', '');
Expand Down
5 changes: 0 additions & 5 deletions lib/src/asms/better_player_asms_utils.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
// Dart imports:
import 'dart:convert';
import 'dart:io';

// Package imports:
import 'package:better_player/src/core/better_player_utils.dart';

// Project imports:
import 'package:better_player/src/dash/better_player_dash_utils.dart';
import 'package:better_player/src/hls/better_player_hls_utils.dart';

Expand Down
7 changes: 5 additions & 2 deletions lib/src/configuration/better_player_configuration.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// Flutter imports:
// Project imports:
import 'package:better_player/better_player.dart';
import 'package:better_player/src/configuration/better_player_translations.dart';
import 'package:better_player/src/subtitles/better_player_subtitles_configuration.dart';
Expand Down Expand Up @@ -100,6 +98,10 @@ class BetterPlayerConfiguration {
/// ignored.
final bool autoDetectFullscreenDeviceOrientation;

///Defines if player should auto detect full screen aspect ration of the video.
///If [deviceOrientationsOnFullScreen] is true this is done automaticaly also.
final bool autoDetectFullscreenAspectRatio;

///Defines flag which enables/disables lifecycle handling (pause on app closed,
///play on app resumed). Default value is true.
final bool handleLifecycle;
Expand Down Expand Up @@ -153,6 +155,7 @@ class BetterPlayerConfiguration {
this.playerVisibilityChangedBehavior,
this.translations,
this.autoDetectFullscreenDeviceOrientation = false,
this.autoDetectFullscreenAspectRatio = false,
this.handleLifecycle = true,
this.autoDispose = true,
this.expandToFill = true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
// Dart imports:
import 'dart:ui';

// Flutter imports:
import 'package:better_player/better_player.dart';

// Project imports:
import 'package:better_player/src/controls/better_player_overflow_menu_item.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
Expand Down
4 changes: 1 addition & 3 deletions lib/src/configuration/better_player_data_source.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// Project imports:

import 'package:better_player/src/configuration/better_player_buffering_configuration.dart';
import 'package:better_player/src/configuration/better_player_data_source_type.dart';
import 'package:better_player/src/configuration/better_player_drm_configuration.dart';
Expand Down Expand Up @@ -62,7 +60,7 @@ class BetterPlayerDataSource {
///Video format hint when data source url has not valid extension.
final BetterPlayerVideoFormat? videoFormat;

///Extension of video without dot. Used only in memory data source.
///Extension of video without dot.
final String? videoExtension;

///Configuration of content protection
Expand Down
1 change: 0 additions & 1 deletion lib/src/configuration/better_player_event.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// Project imports:
import 'package:better_player/src/configuration/better_player_event_type.dart';

///Event that happens in player. It can be used to determine current player state
Expand Down
1 change: 1 addition & 0 deletions lib/src/configuration/better_player_event_type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ enum BetterPlayerEventType {
bufferingStart,
bufferingUpdate,
bufferingEnd,
changedPlaylistItem,
}
5 changes: 0 additions & 5 deletions lib/src/controls/better_player_controls_state.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
// Dart imports:
import 'dart:io';
import 'dart:math';

// Project imports:
import 'package:better_player/better_player.dart';
import 'package:better_player/src/asms/better_player_asms_audio_track.dart';
import 'package:better_player/src/asms/better_player_asms_track.dart';
import 'package:better_player/src/controls/better_player_clickable_widget.dart';
import 'package:better_player/src/core/better_player_utils.dart';
import 'package:better_player/src/video_player/video_player.dart';

// Flutter imports:
import 'package:collection/collection.dart' show IterableExtension;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
Expand Down
Loading

0 comments on commit 9ad3e88

Please sign in to comment.