web-dev-qa-db-fra.com

Comment obtenir la durée de AVPlayer (pas AVAudioPlayer)?

Je voudrais créer un UISlider (scrubber) pour mon AVPlayer. Mais comme ce n'est pas un AVAudioPlayer, il n'a pas de durée intégrée. Une suggestion sur la façon de créer le curseur pour l'avance rapide, le rembobinage et la progression de la lecture?

J'ai lu le document sur AVPlayer, il a un SeeToTime intégré ou SeekToTime: toléranceBefore: toléranceAfter :. Je ne le comprends pas vraiment. Serait-ce la réponse pour mon curseur? AVPlayer a également addPeriodicTimeObserverForInterval: queue: usingBlock:, est-ce pour obtenir la durée de ma piste? Quelqu'un peut-il me donner un exemple sur la façon d'implémenter ce code? Je ne suis pas fan de la documentation d'Apple. Cela semble très difficile à comprendre.

40
slowman21
self.player.currentItem.asset.duration

Je l'ai!

134
slowman21

en-têtes

#import <AVFoundation/AVPlayer.h>
#import <AVFoundation/AVPlayerItem.h>
#import <AVFoundation/AVAsset.h>

code

CMTime duration = self.player.currentItem.asset.duration;
float seconds = CMTimeGetSeconds(duration);
NSLog(@"duration: %.2f", seconds);

cadres

AVFoundation
CoreMedia
36
neoneye

Pour Swift pour obtenir la durée en secondes

if let duration = player.currentItem?.asset.duration {
    let seconds = CMTimeGetSeconds(duration)
    print("Seconds :: \(seconds)")
}
15
Hardik Thakkar

Depuis iOS 4.3, vous pouvez utiliser la version légèrement plus courte:

self.player.currentItem.duration;
11
Douglas

Noté de StitchedStreamPlayer

Tu devrais utiliser player.currentItem.duration

- (CMTime)playerItemDuration
{
    AVPlayerItem *thePlayerItem = [player currentItem];
    if (thePlayerItem.status == AVPlayerItemStatusReadyToPlay)
    {        
        /* 
         NOTE:
         Because of the dynamic nature of HTTP Live Streaming Media, the best practice 
         for obtaining the duration of an AVPlayerItem object has changed in iOS 4.3. 
         Prior to iOS 4.3, you would obtain the duration of a player item by fetching 
         the value of the duration property of its associated AVAsset object. However, 
         note that for HTTP Live Streaming Media the duration of a player item during 
         any particular playback session may differ from the duration of its asset. For 
         this reason a new key-value observable duration property has been defined on 
         AVPlayerItem.

         See the AV Foundation Release Notes for iOS 4.3 for more information.
         */     

        return([playerItem duration]);
    }

    return(kCMTimeInvalid);
}
4
onmyway133

Dans cet exemple, avPlayer est l'instance AVPlayer.

J'ai créé un contrôle vidéo qui utilise les éléments suivants:

pour positionner le curseur, utilisez quelque chose comme ceci pour obtenir le pourcentage de la tête de lecture dans le film, vous devrez déclencher cette fonction à plusieurs reprises. Je lancerais donc la fonction comme:

float scrubberBarLocation = (scrubberBgImageView.frame.size.width / 100.0f) * [self moviePercentage];


- (float)moviePercentage {

    CMTime t1 = [avPlayer currentTime];
    CMTime t2 = avPlayer.currentItem.asset.duration;

    float myCurrentTime = CMTimeGetSeconds(t1);
    float myDuration = CMTimeGetSeconds(t2);

    float percent = (myCurrentTime / myDuration)*100.0f;
    return percent;

}

Ensuite, pour mettre à jour la vidéo, je ferais quelque chose comme:

- (void)updateVideoPercent:(float)thisPercent {

    CMTime t2 = avPlayer.currentItem.asset.duration;
    float myDuration = CMTimeGetSeconds(t2);

    float result = myDuration * thisPercent /100.0f;

    //NSLog(@"this result = %f",result); // debug

    CMTime seekTime = CMTimeMake(result, 1);

    [avPlayer seekToTime:seekTime];

}
3
r farnell

Swift 5

Mettez ce code dans une fonction que vous vouliez:

let duration = player.currentItem?.duration.seconds ?? 0
let playDuration = formatTime(seconds: duration) //Duration RESULT

Créez une fonction appelée: formatTime (secondes: Double)

func formatTime(seconds: Double) -> String {
    let result = timeDivider(seconds: seconds)
    let hoursString = "\(result.hours)"
    var minutesString = "\(result.minutes)"
    var secondsString = "\(result.seconds)"

    if minutesString.count == 1 {
        minutesString = "0\(result.minutes)"
    }
    if secondsString.count == 1 {
        secondsString = "0\(result.seconds)"
    }

    var time = "\(hoursString):"
    if result.hours >= 1 {
        time.append("\(minutesString):\(secondsString)")
    }
    else {
        time = "\(minutesString):\(secondsString)"
    }
    return time
}

Ensuite, une autre fonction pour traduire les secondes en heures, minutes et secondes. Étant donné que les secondes qui, par layerLayer.player? .CurrentItem? .Duration.seconds, auront un double long, cela est nécessaire pour devenir lisible par l'homme.

func timeDivider(seconds: Double) -> (hours: Int, minutes: Int, seconds: Int) {
    guard !(seconds.isNaN || seconds.isInfinite) else {
        return (0,0,0)
    }
    let secs: Int = Int(seconds)
    let hours = secs / 3600
    let minutes = (secs % 3600) / 60
    let seconds = (secs % 3600) % 60
    return (hours, minutes, seconds)
}

J'espère que votre réponse est complète.

1
Angela Puspitasari