noreasonprojects / modernavplayer Goto Github PK
View Code? Open in Web Editor NEWModernAVPlayer is a persistence AVPlayer wrapper
License: MIT License
ModernAVPlayer is a persistence AVPlayer wrapper
License: MIT License
Hi,
When a call recieved, or switched to camera app to take video, after interruption endded audio is not started.. i'm testing on iOS 13.6..
IS there a way to override interruption callbacks?. is The code below responsible for not resuming the audio playback after interruption?
/* Do not set any call back on interruption ended when user play from another app */ private func pauseByInterruption() { let state = PausedState(context: context) if !audioSession.secondaryAudioShouldBeSilencedHint { state.onInterruptionEnded = { [weak state] in state?.play() } } changeState(state: state) }
Hi
How can we apply loop on a track to repeat?
Thanks
In the development, I realize that this variable can be changed sometimes, for example we want to change the remoteURL, data image or other value. However, because this variable is a let variable, we are not able to do that. I suggest that it should be a var variable and update a new function like this.
// ModernAVPlayerMedia.swift
public var assetOptions: [String: Any]?
public func setAssetOptions(asset: [String: Any]?) {
self.assetOptions = asset
}
Could you please revise in the next relesae?
The song has been ended because the time is over. However, the remote-center it still re-play again without stopping.
Cache Audio for remote URL
Nice job!
Could you provide an example for using CarPlay?
Thank You!
In iOS12 the playback stops when the user opens the camera app.
This happens due to AudioSession receiving a notification thatrouteAudioChanged
acts on, the reason being .unknown
which will change the state of the player to paused.
This is unintended behaviour. An interruption should only happen if the camera goes to video mode. We have tested this a fair bit and the issue is not present in iOS13. We have run tests with leaving out the check for .unknown
, in line 205 of PlayingState.swift. Everything still works fine without that check, as InterruptionAudioService will act as intended with proper handling of going to the video mode.
I hope that you will have time soon to attend this minor correction. If wanted I could prepare a pull-request with this change :-)
I keep getting this error when trying to observe the player's state: player.rx.state
Fatal error: Executing on background thread. Please use 'MainScheduler.instance.schedule' to schedule work on main thread.: file /path/ios-app/Pods/RxSwift/RxSwift/Schedulers/MainScheduler.swift, line 43
Code (as per example):
private let player = ModernAVPlayer.init()
var stateObservable: Observable<ModernAVPlayer.State>
private let stateSubject = BehaviorSubject<ModernAVPlayer.State>(value: .initialization)
private let concurrentBackgroundScheduler = ConcurrentDispatchQueueScheduler(qos: .background)
let output: Output
struct Output {
var stateObservable: Observable<ModernAVPlayer.State>
}
init() {
output = Output(stateObservable: stateSubject.asObservable())
player.rx.state
.observeOn(concurrentBackgroundScheduler)
.subscribe(stateSubject)
.disposed(by: disposeBag)
}
Hi,
I came across a strange crash on Firebase...
Fatal Exception: NSInvalidArgumentException
An instance of AVPlayer cannot remove a time observer that was added by a different instance of AVPlayer.
PlayingState.routeAudioChanged(reason:)
Trace:
-[AVPlayer _removeAllLayers]
PlayingState.swift - Line 193
PlayingState.routeAudioChanged(reason:) + 193
PlayingState.swift - Line 65
partial apply for closure #1 in PlayingState.init(context:itemPlaybackObservingService:routeAudioService:interruptionAudioService:audioSession:) + 65
RouteAudioService.swift - Line 63
ModernAVPlayerRouteAudioService.audioRouteChanged(notification:) + 63
Hİ,
I just pod updated to 1.6.0 version but my app crashes on latest version on this line.. is there any code changes to that section? am i using it wrong in the latest version?
let playerMetaData = ModernAVPlayerMediaMetadata(title: title,
albumTitle: albumTitle,
artist: artist,
image: placeHolderImageData,
remoteImageUrl: remoteImageURL)
player.updateMetadata(playerMetaData)
Note: This code part executed on main thread with DispatchQueue.main.async {}
Hi,
some of our users experiencing fatal crash in our app
Crash is related to
ModernAVPlayer
- Line 4362331420
ModernAVPlayerNowPlayingService.overrideInfoCenter(for:value:)
and
NowPlayingService.swift - Line 92
closure #1 in ModernAVPlayerNowPlayingService.updateRemoteImage(url:) + 92
- Line 4362332792
thunk for @escaping @callee_guaranteed (@guaranteed Data?, @guaranteed NSURLResponse?, @guaranteed Error?) -> () + 4362332792
i think it happens when we provide the remoteimage..
i personally cant reproduce this crash but firebase crashlytics keeps popping this crash..
Crashed: NSOperationQueue 0x105d5fc40 (QOS: UNSPECIFIED)
EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000000000000
we cant remove support for remoteimage because nowplaying info albumart is remote image and we dont use image cache so it must be downloaded using this method,
let playerMetaData = ModernAVPlayerMediaMetadata(title: title,
albumTitle: albumTitle,
artist: artist,
image: placeHolderImageData,
remoteImageUrl: remoteImageURL)
player.updateMetadata(playerMetaData)
am i missing something or using this method wrong?
Hi,
is it possible to support tvOS without any development? i want to use modernavplayer with my tvOS target but pod install says its not compatible with tvOS
Seek on stream media (no duration) is not allow for now.
Working on it.
if I tap on the next, previous button in the player screen or remote control center. Sometimes player.rx.itemDuration return a NaN value. Thus, we cannot change the position of the slider time running.
// Display item duration
player.rx.itemDuration
.observeOn(concurrentBackgroundScheduler)
.filter { $0 != nil }
.map { String(format: "%.2f", $0!) }
.asDriver(onErrorJustReturn: "error")
.drive(onNext: setEndDurationTime)
.disposed(by: disposeBag)
func setEndDurationTime(dur: String?) {
// dur: NaN sometimes if we play quickly
if let time = dur?.toDouble().playTimeString {
self.lblEnd.text = time
}
}
It is required because I use authentication and JWT to secure my content.
prevTrackCommand, nextTrackCommand are not available even if I added them into remoteCommands. But skipBackwardCommand(), skipForwardCommand() commands work well. I want prev and next commands work, please help
1、ModernAVPlayerRemoteCommandFactoryV04playE0AA0bcdE0VyFSo08MPRemoteE13HandlerStatusVSo0hE5EventCcfU0_
2、ModernAVPlayerRemoteCommandFactoryV015togglePlayPauseE0AA0bcdE0VyFSo08MPRemoteE13HandlerStatusVSo0jE5EventCcfU0_
Thanks for a great framework! It has saved me for a lot of hassle in dealing with AVPlayer
👍👍
When using ModernAVPlayerConfiguration
, the MPRemoteCommandCenter
seems to never show for the configured ModernAVPlayer
. One have to create a custom implementation of PlayerConfiguration
and override the audioSessionCategoryOptions
to get it to appear.
This was broken in 1.7.3, and is not an issue in 1.7.2.
// Example:
struct CustomPlayerConfiguration: PlayerConfiguration {
let audioSessionCategoryOptions: AVAudioSession.CategoryOptions = []
// ....
}
When there are multiple instances, itemPlayToEndTime will interfere with each other
Audio doesn't play sometime. It hang up between Loading — Loaded — Buffering - Waiting For Network - Loading — Loaded — Buffering — Waiting For Network - Loading... . Sometime audio played but takes too much time.
Logs :
02:31:15076 [🔈][PlayerContext.swift]:85 :: Loading
2018-08-20 14:31:15.092040+0530 AudecibelPodcast[3935:1169149] CredStore - performQuery - Error copying matching creds. Error=-25300, query={
class = inet;
"m_Limit" = "m_LimitAll";
"r_Attributes" = 1;
sync = syna;
}
2018-08-20 14:31:15.099437+0530 AudecibelPodcast[3935:1163830] [framework] CUICatalog: Invalid asset name supplied: ''
02:31:18381 [🔈][PlayerContext.swift]:85 :: Loaded
02:31:18382 [🔈][PlayerContext.swift]:85 :: Buffering
2018-08-20 14:31:18.387123+0530 AudecibelPodcast[3935:1163830] [framework] CUICatalog: Invalid asset name supplied: ''
02:31:21389 [🔈][PlayerContext.swift]:85 :: Waiting For Network
2018-08-20 14:31:21.396182+0530 AudecibelPodcast[3935:1163830] [framework] CUICatalog: Invalid asset name supplied: ''
2018-08-20 14:31:21.399674+0530 AudecibelPodcast[3935:1169965] Task <BD7D92BA-908D-41B6-AAD7-0C88881EAC01>.<1> finished with error - code: -999
02:31:21888 [🔈][PlayerContext.swift]:85 :: Loading
2018-08-20 14:31:21.905569+0530 AudecibelPodcast[3935:1169965] CredStore - performQuery - Error copying matching creds. Error=-25300, query={
class = inet;
"m_Limit" = "m_LimitAll";
"r_Attributes" = 1;
sync = syna;
}
2018-08-20 14:31:21.915624+0530 AudecibelPodcast[3935:1163830] [framework] CUICatalog: Invalid asset name supplied: ''
02:31:24953 [🔈][PlayerContext.swift]:85 :: Loaded
~~~ PLUGIN: customAttribute=attribute0
02:31:24954 [🔈][PlayerContext.swift]:85 :: Buffering
2018-08-20 14:31:24.959167+0530 AudecibelPodcast[3935:1163830] [framework] CUICatalog: Invalid asset name supplied: ''
Please Help me solved this problem.
Thanks
I want to simplify audiotracks/subtitles selection
Subtitles
var currentSelectedSubtitle: ModernSubtitle { get }
getAvailableSubtitles() -> [ModernSubtitle]
selectSubtitle(ModernSubtitle)
AudioTacks
var currentSelectedAudioTrack: ModernAudioTrack { get }
getAvailableAudioTracks() -> [ModernAudioTrack]
selectAudioTrack(ModernAudioTrack)
Where is the best place to implement this according to the current implementation
Guessing as part of PlayerMediaItem
Protocol and cast it when getting currentMedia
from ModerAVPlayer instance
Hi,
i have a strange bug, sometimes on some devices audio stops playing right after 15-20 seconds, and it only happens on real device, when i connect my device to xcode, no errors, no warnings and no stops... it started with a specific version of modernavplayer but i dont remember which one...
any help would be great
Please add preferredForwardBufferDuration or other option to set buffer limiting size; when user "PAUSE" a live stream or a large video buffering is not stopped and cause battery consuming or network data usage issue.
also please add an option for getting buffered duration
I am quite confused about how to write the next and previous a song command. Could you please help?
Sometimes there are cases where you need precise seeking which is called like this
player.seek(to: CMTime(seconds: 100, preferredTimescale: CMTimeScale(NSEC_PER_SEC)), toleranceBefore: .zero, toleranceAfter: .zero)
currently seeking is not precise which is fine in most cases, however it would be nice to have precise seek
proposed solution extend current seek methods with another one with additional parameter isPrecise
or isAccurate
to not introduce breaking changes, example:
existing:
public func seek(position: Double) {
context.seek(position: position, isPrecise: false)
}
new:
public func seek(position: Double, isPrecise: Bool) {
context.seek(position: position, isPrecise: isPrecise)
}
would you approve this type of PR if I do? @raphrel
Is it available for adjusting playback speed?
Please add support playback speed for both local and remote files.
This framework will be perfect if you have this feature. :))
Thank you.
Thank you for creating a good library.
When playing through URL, how do I preload so that buffering does not take place?
Also, are there any plans to support media caching?
Would be nice to have a callback that indicates seekableTimeRanages changed for the current item, would be useful to update min and max for seek bar accordingly, instead of relying on asset duration. Super useful for lives which have sliding DVR window and I need to display UI accordingly
Proposed solution: extend current delegate api with func
func modernAVPlayer(_ player: ModernAVPlayer, didSeekableTimeRangesChange range: (start: Double, end: Double))
Hi,
There is a strange behavior, audio pauses and continues after recieving phone call, its fine and expected behavior but when you try to make a call while audio is playing, audio stops but won't resume playing after phone call ends....
Hi Raphrel,
Thanks for developing such an easy to use yet powerful package for Swift.
I am using your package to prototype an ios app using SwiftUI. Everything is working fine except the "duration" of the track. I can't find a way to retrieve this information from the player.
Any help is appreciated.
Thanks,
Amin
I'm trying to implement next/previous media, yet, was unable to do so using ModernAVPlayer
library.
Code example:
func modernAVPlayer(_ player: ModernAVPlayer, didItemPlayToEndTime endTime: Double) { self.next() } func next() { self.player.load(media: nextMediaItem, autostart: true) }
Crash:
Is related to durationTimer
Scenerio:
If I autoplay next media before delegate method modernAVPlayer(player,didItemPlayToEndTime)
is called, then crash doesn't occur, however, if media is is finished playing and from delegate callback next is invoked, then crash occured.
Expectation:
Try to share some example/sample code, so that next/previous media can be implemented like media queue concept.
Nice job, thanks!
Feature request: Add the possibility to set gains and visualize in a VU-Meter?
Regards,
Hi. Thanks for making a good library.
I know that NowPlayingInfo is updated automatically when I update ModernAVPlayerMediaMetadata, but I don't know how to remove NowPlayingInfo.
How to Remove NowPlayingInfo?
Is it possible to show an example of the player implemented in SwiftUI?
BackgroundTask] Background Task 11 ("Called by ModernAVPlayer, from $s14ModernAVPlayer17LoadingMediaStateC14contextUpdatedyyF"), was created over 30 seconds ago. In applications running in the background, this creates a risk of termination. Remember to call UIApplication.endBackgroundTask(_:) for your task in a timely manner to avoid this.
This is message log i got from Xcode. I suppose that the song has been loading too long but there was no response and the background task is still running.
When fetching videos from the camera roll, we call PHImageManager#requestAVAsset
.
But, ModernAVPlayer
doesn't let us set an AVURLAsset
object ourselves, so there doesn't seem to be a way of loading something from the camera roll without going through the underlying AVPLayer
.
in LoadingMediaState.swift
:
private func createItem(with media: PlayerMedia) -> AVPlayerItem {
let asset = AVURLAsset(url: media.url, options: media.assetOptions)
return AVPlayerItem(asset: asset, automaticallyLoadedAssetKeys: ["playable", "duration"])
}
Should I just go through the AVPlayer
and let the KVO stuff from the ModernAVPlayer
reconcile the difference?
Reloading Item internally is causing limitations for consumers:
1. If playback url has a lifetime I need to get new url and reload with that one
2. Some SDKs are forcing to load stream in a custom way (like Google IMA sdk for ads, etc.)
Proposed solution:
In the example, functions are passed to map
or subscribe(onNext:)
.
By referencing an instance method, you're actually making a strong reference to self and thus creating a retain cycle.
Example:
ModernAVPlayer/Example/ViewController.swift
Line 313 in 2b3450e
Good job!
Feature request: Add alarms like Apple Clock App but with an url to play.
Regards,
Hi,
After updating the pods ModernAVPlayerMedia is taking assetOptions dictionary in the constructor.
let media = ModernAVPlayerMedia(assetOptions: nil, url: liveUrl, type: .stream, isLive: true, metadata: nil)
Can you share what is assetOptions and how we can use it?
Thanks
Hello!
I'm learning iOS by writing Podcasts app. And I have 2 issues:
Previous item continues playing when I tap on another episode from my list.
I have noticed that when I tap "Stop" from Control Center and then tap on another episode, everything's working correctly.
I need to show how much time is left, but I couldn't find how can I get a duration of current media.
I would really appreciate it if you could help me. I'm using PlayerService as a wrapper for all of the player methods. And I present the player from EpisodesViewController.
You can look at my code here:
https://github.com/Karambirov/Podcasts/tree/feature/player-service
currently player.automaticallyWaitsToMinimizeStalling
is set to false in init state, would be nice to be able to change this with configuration
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.