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
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 ?
En plus :
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];
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 ?
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
Désolée, je connais les principes de vidéo mais pas vraiment les frameworks
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
C'est my bad. Je pensais de CMTimeMake ::)
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
Ah, dans le buffet, parmi les assiettes
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