iOS- 如何在AVPlayer中实现seektotime(从URL播放歌曲)?

问题描述 投票:0回答:4

我想在AVPlayer中实现Scrubber(UISlider)。我已经尝试过,但是没有完全成功(有时滑块显示不正确的值,有时进度显示进度条)。任何建议都会很棒。

-(void)playButtonClicked
{

    // checks internet connnection : working or not

    if([InternetUtility testInternetConnection])

    {

        if (audioButton.selected)
        {
            audioButton.selected = NO;
            printf("\n\ndo audioButton.selected = NO; \n\n");

        }

        else
        {
            printf("\n\ndo audioButton.selected = YES; \n\n");
            audioButton.selected = YES;
        }

        if (!isAlredayPlaying) {
        printf("\n\nStarted song from 0\n");
        isAlredayPlaying=YES;




        NSURL *url = [NSURL URLWithString:AUDIO_FILE_URL];


        playerItem = [AVPlayerItem playerItemWithURL:url];



        player = [AVPlayer playerWithPlayerItem:playerItem];
        player.volume=5.0;
        [self.audioSliderBar setMinimumValue:0.0];
        nsTimer=[NSTimer scheduledTimerWithTimeInterval:1.0/60.0 target:self selector:@selector(updateTime:) userInfo:nil repeats:YES];
        [player play];


    }

    else
    {
        if (isCurrentlyPlaying)

        {
            [nsTimer invalidate];
            isCurrentlyPlaying=NO;
            [player pause];


        }
        else
        {
            nsTimer=[NSTimer scheduledTimerWithTimeInterval:1.0/60.0 target:self selector:@selector(updateTime:) userInfo:nil repeats:YES];
            isCurrentlyPlaying=YES;
            [player play];

        }

     }
}      // internet connection check funtion, ended


    else {
        [ViewUtilities showAlert:INTERNET_CONNETION_TITLE :INTERNET_CONNECTION_MESSAGE];

    }
}

    - (void)updateTime:(NSTimer *)timer {


    currentTime = CMTimeGetSeconds(playerItem.currentTime);

    duration = CMTimeGetSeconds(playerItem.duration);


    if (currentTime==duration) {
        [self itemDidFinishPlaying];

    }

    [ self.audioSliderBar setValue:(currentTime/duration)];

    float minutes = floor(currentTime/60);
    seconds =currentTime - (minutes * 60);

    float duration_minutes = floor(duration/60);
    duration_seconds =
    duration - (duration_minutes * 60);



    NSString *timeInfoString = [[NSString alloc]
                                initWithFormat:@"%0.0f:%0.0f",
                                minutes, seconds ];//],
    //duration_minutes, duration_seconds];

    if  (!(player.currentItem && player.rate != 0 )&& isCurrentlyPlaying)
    {
        if (audioPlayerWillStop) {

            isAlredayPlaying=NO;
            [nsTimer invalidate];

        }

        else {

            [player play];
            printf("\n\n\n Force to play song...");

        }


    }
    self.audioCurrentTimeLabel.text = timeInfoString;

}

-(IBAction)audioPlayerValueChanged:(UISlider *)aSlider {

 CMTime newSeekTime = CMTimeMakeWithSeconds(aSlider.value*seconds,1) ;
[player seekToTime:newSeekTime];

// 此代码无法完全正常工作(滑块值会不断返回)请帮助

}
ios objective-c avplayer
4个回答
1
投票

您可以使用我的已实现方法。该代码可以正常工作。

        #define NSEC_PER_SEC 1000000000ull
        -(void)funSeekPlayer
        {
               CMTime playerDuration = [self playerItemDuration];
               if (CMTIME_IS_INVALID(playerDuration)) {
                 return;
               }

               float minValue = [aSlider minimumValue];
               float maxValue = [aSlider maximumValue];
               float value = [aSlider value];

               double time = duration * (value - minValue) / (maxValue - minValue);

               [player seekToTime:CMTimeMakeWithSeconds(CMTimeMakeWithSeconds(time, NSEC_PER_SEC), NSEC_PER_SEC) completionHandler:^(BOOL finished) {
                   dispatch_async(dispatch_get_main_queue(), ^{
                    // Do Your next task
                   });
               }];

         }

         - (CMTime)playerItemDuration
         {
            AVPlayerItem *playerItem = [player currentItem];
            if (playerItem.status == AVPlayerItemStatusReadyToPlay)
            {
                return([playerItem duration]);
            }

            return(kCMTimeInvalid);
         }


0
投票

您必须知道确切的长度(以秒为单位)的音乐/视频。然后,您可以使用UISlider以秒为单位计算开始播放音乐/视频的时间。最后在您的.seekToTime(CMTimeMake(valueInSecond, 1))对象上使用了AVPlayer


0
投票

如果您正在使用HLS(m3u8)视频点播流,并且想要向前搜索,则需要等待所有下载的时间范围。这意味着,如果要向前搜索60秒,则AVPlayer应该加载这60秒的所有时间范围。您可以像这样检查:

- (double) loadedTimeRangesDuration
{
    double result = 0;
    NSArray* ranges = self.player.currentItem.loadedTimeRanges;
    if (ranges != nil && ranges.count > 0)
    {
        CMTimeRange range = [[ranges objectAtIndex:0] CMTimeRangeValue];
        double duration = CMTimeGetSeconds(range.duration);
        result = duration;
    }

    return result;
}

0
投票

对于提前10秒钟移动视频,我已经使用了此代码,它对我有用

浮动tempTime = CMTimeGetSeconds(player.currentItem.duration)+ 10;

CMTime targetTime = CMTimeMakeWithSeconds(tempTime,NSEC_PER_SEC);

[玩家seekToTime:targetTime];

© www.soinside.com 2019 - 2024. All rights reserved.