AVPlayerItem : lecture du currentTime en live

Bonjour à  tous


 


Je me casse la tête sur la valeur du currentTime prise d'un AVPlayerItem en mode lecture. L 'affichage de cette valeur se passe bien au fur et à  mesure que la vidéo se lit mais la valeur semble erronée.


 


Et lorsque j'arrête la lecture de ma vidéo, et que, cette fois ci j'avance image par image, j'obtiens une autre valeur, et du currentTime et du timeScale, qui elle, me semble plus juste.


 


En fait, j'ai l'impression que l'utilisation de fonctions pour l'avance image par image, implique des calculs et prend donc du temps, temps qui "permettrait" à  ma séquence de se caler et donc donner un temps juste...mais là  ce n'est qu'une impression.


 


Quelqu'un a-t-il une idée de cette différence de valeur (exemple de valeur : currentTime.value: 249627 et currentTime.TimeScale : 9000 et en avance image par image : currentTime.value: 1704 et currentTime.TimeScale : 600) ?


 


Voici le code qui permet l'affichage en live (via un Timer) : 



-(void) checkMovieTime:(NSTimer *)timer //et audio
{

if (monPlayer) {

[infoCurrentImg setStringValue:[NSString stringWithFormat:@%li,(long)timeSlider.integerValue ]];

infoCurrentTV.stringValue = [NSString stringWithFormat:@Current TV : %lld, monPlayerItem.currentTime.value];

[infoDurationTimaScale setStringValue:[NSString stringWithFormat:@%.2d duration 1 timeScale,monPlayerItem.duration.timescale]];
}
}


Et mon code d'avance image par image : 



case 124 : //fleche D

test = [monPlayerItem currentTime];
test1 = [monPlayer currentTime];

unplayableLabel.hidden = YES;

timeSlider.integerValue ++;

[monPlayer pause];

[self setCurrentImg:timeSlider.integerValue];

test = [monPlayerItem currentTime]; //diférent du précédent test ET cette valeur est juste
test1 = [monPlayer currentTime];

break;

et setCurrentImg : 



- (void)setCurrentImg:(NSInteger)img // en img
{
if ([arraySecImg count]>0)
{
[self setCurrentTimeInTime:[[arraySecImg objectAtIndex:img] doubleValue]];
}

}

et pour finir setCurrentTimeInTime : 



- (void)setCurrentTimeInTime:(double)time // en sec
{

CMTime requested = CMTimeMakeWithSeconds(time, monPlayerItem.duration.timescale);
[monPlayerItem seekToTime:requested toleranceBefore:kCMTimeZero toleranceAfter: kCMTimeZero ];//kCMTimePositiveInfinity

//Afficher l'image en cours en bénéficiant du live du slider
[self afficherLImageEnCours:myAsset item:monPlayerItem ];


}

Réponses

  • Joanna CarterJoanna Carter Membre, Modérateur

    Franchement, le code me paraà®t un peu bizarre mais il y a un truc qui me gène : c'este qu'en setCurrentTime, tu passes un Double.


     


    On a déjà  parlé de CMTime.


     


    Le truc, c'est de travailler toujours en Int pour que le "value" soit en nombre de "frames" et le "timescale" soit le nombres de "fps".


     


    Du coup, pour 40 secondes à  30fps, il faut compter un "value" de 1200 pour le dernière "frame"


     


    ça t'aide ?


  • Joanna CarterJoanna Carter Membre, Modérateur

    En plus :



    - (void)setCurrentTimeInTime:(double)time // en sec
    {
    CMTime requested = CMTimeMakeWithSeconds(time, monPlayerItem.duration.timescale);
    [monPlayerItem seekToTime:requested toleranceBefore:kCMTimeZero toleranceAfter: kCMTimeZero ];//kCMTimePositiveInfinity

    //Afficher l'image en cours en bénéficiant du live du slider
    [self afficherLImageEnCours:myAsset item:monPlayerItem ];
    }

    Pourquoi tu passes un double  ?


     


    Pourquoi tu prends monPlayerItem.duration.timescale ? Tu l'as déjà  initialisé à  ton "framerate" ailleurs ?


     


    La valeur que tu passes comme time ; tu comprends que c'est en "frames", pas en secondes ?


  • Merci de ta réponse Joanna Carter


     


    Non en fait, dans mon cas, j'ai, au moment de l'acquisition de la vidéo, récupéré un tableau du time en seconde de chaque image (arraySecImg) donc setCurrentTimeInTime récupère bien un double. Mais c'est plus à  titre informatif.


     


    Mais en fait, j'ai mis les 2 dernières fonctions, plus pour info qu'autre chose, simplement pour montrer qu'il y a du calcul et de la récupération d'info. 


     


    En fait, mon problème c'est que le 1er 


    test = [monPlayerItem currentTime];


    test1 = [monPlayer currentTime];


     


    ne donne pas les mêmes valeurs que mon deuxième 


                test = [monPlayerItem currentTime];


                test1 = [monPlayer currentTime];
  • Nos messages se sont croisés


     


    Oui oui, comme je te le disais, je prends bien des secondes ici, mais encore une fois cela n'a rien à  voir avec mon pbl puisqu'il ne s'agit que de récupérer des infos que j'avais calculées avant.

    Mon souci est plut^t dans la deuxième fonction au niveau du test en début et en fin qui ne donne pas les mêmes résultats


     


    En revanche je ne comprends pas ta question : Pourquoi tu prends monPlayerItem.duration.timescale ? Tu l'as déjà  initialisé à  ton "framerate" ailleurs ?


    => mon monPlayerItem a bien été initialisé avant et il fonctionne puisque je vois bien ma séquence vidéo

  • Joanna CarterJoanna Carter Membre, Modérateur

    Mais CMTimeMakeWithSeconds(time, monPlayerItem.duration.timescale) ne prend pas le time en secondes, c'est toujours en frames.


     


    Du coup, CMTimeMakeWithSeconds(20, 30) fait un durée de â…” secondes.


     


    Et tu appelles [monPlayer pause]; après que tu as pris les premières valeurs mais avant les dernières?


     


    Je manque toujours quelque chose ?


  • Enfin, pour répondre à  ta première question : "ça t'aide ?".....pas vraiment !!!


    EN fait, je suis sur que les valeurs du 2e tests sont justes car en fait, j'essaye simplement de remettre à  jour une appli que j'avais fait il y a pas mal de temps sous Xcode 5 mais je suis passé sous Sierra et Xcode 8 ce qui fait que le framework QTKit n'est plus, il faut donc que je passe sous avfoundation


  • Non CMTimeMakeWithSeconds prend un float en premier, donc bien des secondes


  • Joanna CarterJoanna Carter Membre, Modérateur


    Enfin, pour répondre à  ta première question : "ça t'aide ?".....pas vraiment !!!




     


    Désolée, je connais les principes de vidéo mais pas vraiment les frameworks 


     




    EN fait, je suis sur que les valeurs du 2e tests sont justes car en fait, j'essaye simplement de remettre à  jour une appli que j'avais fait il y a pas mal de temps sous Xcode 5 mais je suis passé sous Sierra et Xcode 8 ce qui fait que le framework QTKit n'est plus, il faut donc que je passe sous avfoundation




     


    Ah ! 

  • Quand aux valeurs, oui je suis d'accord avec toi, mais ce qui me surprends, c'est que le timeScale change


  • En revanche, tu m'a peut être mis sur la voie : si je divise les deux valeurs d'avant (10000 fois supérieures à  celles d'après) et je compare avec la division des deux valeurs d'après, je suis quasiment sur le même time en seconde (justifié comme tu l'as dit par un Pause après le premier test...

    Je vais fouiner dans ce sens


  • Joanna CarterJoanna Carter Membre, Modérateur


    Non CMTimeMakeWithSeconds prend un float en premier, donc bien des secondes




     


    C'est my bad. Je pensais de CMTimeMake  ::)

  • Joanna CarterJoanna Carter Membre, Modérateur

    Et j'ai trouvé cette article sure SO qui n'est pas sur AVPlayerItem mais les principes sont presque pareils http://stackoverflow.com/questions/41904722/playing-avplayeritem-currenttime-in-seconds-return-inconsistent-values


  • Oui j'ai procédé de la même façon pour récupérer les times en secondes. Comme lui, j'avais des valeurs non trier. En revanche, j'ai fait autrement : j'ai trié mon tableau de récupération des times ce qui me donne la même chose.


    Mais selon toi, mon problème serait lié à  la même chose : un observateur qui me donne des valeurs d'un temps qui ne serait pas le currentTime mais simplement dans le buffet ?


    Si c'est le cas, je ne suis pas encore assez doué pour corriger cela


  • Joanna CarterJoanna Carter Membre, Modérateur
    avril 2017 modifié #15


    ... mais simplement dans le buffet ?




     


    Ah, dans le buffet, parmi les assiettes 


     




    Si c'est le cas, je ne suis pas encore assez doué pour corriger cela




     


    Malheureusement, ni moi  :(


  • heu...petit clavier...ou gros doigts...ou correction automatique de m.... !!!!!!!!


     


    c'est bien buffer que je voulais écrire  ;D


  • OK je viens de comprendre :


     


    Lorsque j'ai récupéré les valeurs en seconde de chaque image, le timeScale du CMTime est bien de 600 ce qui doit correspondre au moment exact où commence l'image. Cela est vrai pour toutes les premières valeurs de chaque début d'image (si je peux m'exprimer ainsi puisqu'il s'agit bien d'un flux).


    En revanche, tout au long de l'apparition de l'image, le timeScale est de 100000 pendant la diffusion (mode play) ou 90000 si je me mets en pause donc que j'arrête le flux.


    Je suis donc très souvent entre le début de la diffusion de l'image et la diffusion de l'image suivante ce qui me donne un timeScale de 90000 ou 100000 et lorsque je passe au moment précis de l'image suivante, le timeScale est de 600.


     


    Voila voila !

  • En tout cas, merci Joanna Carter pour ta piste 


Connectez-vous ou Inscrivez-vous pour répondre.