Here i am sending code for player view of panframe sdk
CMTime t = [pfAsset getPlaybackTime];
CMTime seekingCM = CMTimeMake(t.value+10000000, t.timescale);
[pfView run];
//[pfAsset stop];
[pfAsset playWithSeekTo:seekingCM onKeyFrame:YES];
slider.value = CMTimeGetSeconds(t);
[pfAsset play];return;
Please advise how it will work.
Related
JWConfig * config = [JWConfig new];
config.file = #"https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8";
self.player = [[JWPlayerController alloc] initWithConfig:config];
[self.player play];
Later on, with the same player instance I can do something like this:
JWPlaylistItem * item = [JWPlaylistItem new];
item.file = #"http://qthttp.apple.com.edgesuite.net/1010qwoeiuryfg/sl.m3u8";
[self.player load:#[ item ]];
[self.player play];
If I have a reference to self.player how can I get the URL of the file that is currently playing?
I have tried:
self.player.config.file
This doesn't work, because it will return the original file from the initialization (bitdash-a.akamaihd.net...)
From the player instance I can't find a way to get a reference to the currently playing playlistItem
There is no way to do this with jw player on iOS. https://github.com/jwplayer/JWPlayer-iOS-SDK-cocoapod/issues/49
The SDK intends to add a getPlaylistItem method for this purpose
I am making an app that plays back audio and I have set it up so that the lock screen gets updated through MPNowPlayingInfoCenter, but I've run into a problem.
At seemingly random times, I get an EXC_BAD_ACCESS error when trying to update the now playing info.
Here's the code that does so:
- (void)updatePlayback
{
if(!active)
return;
NowPlayingController* npc = [AudioController nowPlayingController];
CMTime elapsed = player.currentTime;
Float64 elInterval = CMTimeGetSeconds(elapsed);
[npc setElapsed:elInterval];
CMTime duration = player.currentItem.duration;
Float64 durInterval = CMTimeGetSeconds(duration);
[npc setRemaining:ceilf(durInterval - elInterval)];
[npc setPlayPauseValue:isPlaying];
if(durInterval > 0)
{
[npc setProgressValue:elInterval/durInterval];
[npc setAudioDuration:durInterval];
}
_activeMetadata[MPMediaItemPropertyPlaybackDuration] = #(durInterval);
_activeMetadata[MPNowPlayingInfoPropertyPlaybackRate] = #(isPlaying);
_activeMetadata[MPNowPlayingInfoPropertyElapsedPlaybackTime] = #(elInterval);
MPNowPlayingInfoCenter* npInfoCenter = [MPNowPlayingInfoCenter defaultCenter];
if(npInfoCenter && _activeMetadata)
{
if([npInfoCenter respondsToSelector:#selector(setNowPlayingInfo:)])
{
//////////THE FOLLOWING LINE TRIGGERS EXC_BAD_ACCESS SOMETIMES////////////
[npInfoCenter setNowPlayingInfo:_activeMetadata];
}
}
}
99.9% of the time, this works, but sometimes when resigning the app to the background or when changing audio files, or just randomly,
[npInfoCenter setNowPlayingInfo:_activeMetadata];
throws EXC_BAD_ACCESS.
Also, _activeMetadata is declared as:
#property (atomic, strong, retain) NSMutableDictionary* activeMetadata;
It is instantiated when the AVPlayer is created:
AVAsset* asset = [AVAsset assetWithURL:[NSURL fileURLWithPath:path]];
AVPlayerItem* playerItem = [AVPlayerItem playerItemWithAsset:asset];
player = [AVPlayer playerWithPlayerItem:playerItem];
CMTime duration = player.currentItem.duration;
NSTimeInterval durInterval = CMTimeGetSeconds(duration);
NSLog(#"%f", durInterval);
MPMediaItemArtwork* albumArtwork = [[MPMediaItemArtwork alloc] initWithImage:[downloader useCachedImage:CacheKeySeriesBanners withName:nil withURL:info[#"image"]]];
NSDictionary* nowPlayingInfo = #{MPMediaItemPropertyTitle:ptString,
MPMediaItemPropertyArtist:spString,
MPMediaItemPropertyArtwork:albumArtwork,
MPMediaItemPropertyAlbumTitle:info[#"title"],
MPMediaItemPropertyPlaybackDuration:#(durInterval),
MPNowPlayingInfoPropertyPlaybackRate:#(1),
MPNowPlayingInfoPropertyElapsedPlaybackTime:#(0)};
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:nowPlayingInfo];
_activeMetadata = [nowPlayingInfo mutableCopy];
updatePlayback is called via a CADisplayLink on every frame.
Any ideas what could be causing the exception?
I think you're calling setNowPlayingInfo way too often. Granted, it really shouldn't crash but there's no need to use CADisplayLink to call it 60 times a second.
So why are you calling it so often? If it's because you want to progress bar to track smoothly, there's still no need. From the MPNowPlayingInfoPropertyElapsedPlaybackTime declaration:
// The elapsed time of the now playing item, in seconds.
// Note the elapsed time will be automatically extrapolated from the previously
// provided elapsed time and playback rate, so updating this property frequently
// is not required (or recommended.)
p.s. I tried the code with an m4a file and found durInterval was NotANumber. With the correct duration and calling setNowPlayingInfo only once, the progress bar tracked fine & nothing crashed.
Apple fixed this crash in iOS 10.3 and above.
So if you want to support iOS 10.2.1 and below, be sure to throttle how often you set [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo property. Perhaps limiting setting the property only once a second.
When I change the currentTime of AVAudioPlayer after pausing the player, it gives a lag (some time in positive and some time in negative).
[self.bookAudioPlayer pause];
[self.bookAudioPlayer setCurrentTime:[currentPage.audioStartTime doubleValue]];
[self.bookAudioPlayer prepareToPlay];
When I print the currentTime and audioStartTime it prints values with slight difference. For example,
audioStartTime : 2.203665, currentTime : 2.194286
audioStartTime : 137.521347, currentTime : 137.508571
I have tried to fix it using the following code but results stay the same.
- (void)fixSetCurentTime:(NSTimeInterval)newTime {
self.currentTime = newTime;
if (self.currentTime != newTime) {
[self prepareToPlay];
self.currentTime = newTime;
}
}
Has anyone experienced this issue? Any pointers for a possible fix?
Note that the MP3 audio frames are about 26 milliseconds long. So, block-based audio compression formats are only (re)startable on time-quantized block boundaries... And the nearest block start might be earlier (or later) in time.
Credit: Apple Developer Forum User (Reference)
I would like my AVPlayer object to automaticly update my UISlider when playing.
I have found a code on this forum that seems to work for other but I'm broken at some point:
CMTime interval = CMTimeMakeWithSeconds(1.0, NSEC_PER_SEC); // 1 second
self.playbackTimeObserver = [self.player addPeriodicTimeObserverForInterval:interval queue:NULL usingBlock:^(CMTime time) {
// update slider value here...
}];
I have inserted this code in my viewDidLoad but I removed "self.playbackTimeObserver" as I can't find what type of object is this. I guess that's why it s not working correctly.
Can you please tell me what type is it and where/how to declare it?
Here is my current code:
- (void)viewDidLoad
{
[super viewDidLoad];
CMTime interval = CMTimeMakeWithSeconds(1.0, NSEC_PER_SEC); // 1 second
[songPlayer addPeriodicTimeObserverForInterval:interval queue:NULL usingBlock:^(CMTime time) {
NSLog(#"seconds = %f", CMTimeGetSeconds(songPlayer.currentTime));
}];
self.mmContainerSearch.hidden = NO;
self.mmContainerDownload.hidden = YES;
self.mmContainerLibrary.hidden = YES;
}
Its type is id. It right in the documentation.
Return Value
An opaque object that you pass as the argument to removeTimeObserver: to cancel observation.
If you never need to remove the time observer, then you don't really need to save the return value. My guess is that as some point you will want to cleanup. At that point, then you will need to call -removeTimeObserver:.
Im am developing an iOS app in Xcode. I am still new to programming.
I am trying to set the volume of an audiotrack while playing it with an AVPlayer. It is working great if a set the time at kCMTimeZero but I want it to set the volume one second after the button was pressed.
Not working
- (IBAction)maxVolButtonPressed:(id)sender {
[audioInputParams1 setVolume:1 atTime:time1];
[self applyAudioMix];
}
Working
- (IBAction)minVolButtonPressed:(id)sender {
[audioInputParams1 setVolume:0 atTime:kCMTimeZero];
[self applyAudioMix];
}
What should I write after atTime if I want a one second delay?
ANSWER:
Ok so I figured it out. You have to add the time where the current item is at the moment. I use setVolumeRampFromStartVolume with a very little time interval instead of setVolume. setVolume fades to the given volume for some reason I haven't figured it out why.
It works for me like this:
CMTime time1 = CMTimeMake(1000, 1000); //2s
CMTime time2 = CMTimeMake(1001, 1000); //3s
CMTime timeCurrent = [player currentTime];
CMTime time1Added = CMTimeAdd(timeCurrent, time1);
CMTime time2Added = CMTimeAdd(timeCurrent, time2);
CMTimeRange fadeInTimeRange = CMTimeRangeFromTimeToTime(time1Added, time2Added);
[audioInputParams1 setVolumeRampFromStartVolume:0 toEndVolume:1 timeRange:fadeInTimeRange];
[self applyAudioMix];
You should do something like this:
- (IBAction)maxVolButtonPressed:(id)sender {
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(setVolume:) userInfo:nil repeats:NO];
}
- (void)setVolume:(id)sender{
[audioInputParams1 setVolume:1 atTime:kCMTimeZero];
[self applyAudioMix];
}
In first method you are saying: wait for 1 second and then call method setVolume:.