Appli Double Ecran vidéo

ZyrolZyrol Membre
15:05 modifié dans API AppKit #1
Bonjour,

Pour ceux qui ne sont pas au courant de mon projet,  je suis en train de réaliser une appli pour un usage sportif avec 2 écran vidéo en lecture parallèle.
Je viens de m'occuper du ralenti, il marche tres bien. Mais il y a quelque chose d'étrange...
J'utilise 4 boutons radio pour sélectionner la vitesse du ralenti (100% (pas de ralenti), 75%, 50%, 25%). Admettons, je lis une vidéo à  vitesse normale (100 %), je clique sur une des 3 vitesses (75,50,25) la vidéo ralenti immédiatement.par contre quand je suis à  une  vitesse lente et que je veux passer à  une vitesse supérieure, je suis obligé de cliquer 2 fois sur le bouton pour que ça fasse effet. c'est pourtant la même procédure qui s'exécute dans les 2 cas (montée et descente).
Voici le code de cette fameuse procédure, si quelqu'un à  une idée...
{
//appel de procedure SetRalenti qui controle quel ralenti a été selectionné
[self SetRalenti:(id)sender];

[movieView2 setRate:ralenti];
[movieView1 setRate:ralenti];

[movieView2 start:self];
[movieView1 start:self];
}
merci

Réponses

  • cbrandtcbrandt Membre
    15:05 modifié #2
    si tu déclares des fonctions C, tu dois les mettre en dehors de toute classe...
    tu peux poster ton .h en entier ?
  • cbrandtcbrandt Membre
    15:05 modifié #3
    bonjour,

    je suppose que tes boutons radio sont groupés dans une nsmatrix, et que l'action de cette nsmatrix déclenche le ralentissement ?

    essaye comme ça:
    <br />- (void) actionMatrix: (id) sender<br />{<br />    [self performSelector: @selector (miseajour:) withObject: self afterDelay: 0.01];<br />}<br /><br />- (void) miseajour: (id) sender<br />{<br />   [self SetRalenti: sender];<br /><br />   [movieView2 setRate:ralenti];<br />   [movieView1 setRate:ralenti];<br />   <br />   [movieView2 start:self];<br />   [movieView1 start:self];<br />}<br />
    


    explications:
    on appelle miseajour après un léger délai d'attente, en tout cas après que actionMatrix soit terminé... comme ça on laisse la matrix finir de mettre à  jour ses boutons après un click
    (je n'ai pas d'explication rationnelle, mais c'est comme ça que j'avais résolu un pb où l'interrogation du bouton cliqué ne me renvoyait pas toujours le bon...)
  • ZyrolZyrol Membre
    15:05 modifié #4
    merci pour cette partie de code.

    Je suis devant un autre problème majeur pour la lecture simultanée :
    Voici le code utilisé :
    {
    Movie movie1=[[movieView1 movie] QTMovie];
    Movie movie2=[[movieView2 movie] QTMovie];

    OSErr err=PrerollMovie(movie1,GetMovieTime(movie1,NULL),GetMoviePreferredRate(movie1));
    err=PrerollMovie(movie2,GetMovieTime(movie2,NULL),GetMoviePreferredRate(movie2));

    //appel de procedure SetRalenti
    [self SetRalenti:(id)sender];

    [movieView2 setRate:ralenti];
    [movieView1 setRate:ralenti];
    [movieView1 start:self];
    [movieView2 start:self];

    }

    La procédure SetRalenti permet de définir la vitesse de ralenti des 2 vidéos. Mon probleme est que les 2 vidéos de démarre pas exactement en meme temps :
    Test d'aprés un flux .dv d'une caméra numérique :
    Vitesse normale : la vidéo 2 est en retard de 8 images par rapport à  la vidéo 1
    ralenti de  25%  :                                        5
            50%  :                                        3
            75%  : Aucun décalage.

    Donc plus la vidéo est ralentie, moins il y a de décalage.

    Comment réduire cet écart ?
  • mpergandmpergand Membre
    novembre 2004 modifié #5
    Je pense que la seule façon d'avoir une synchro parfaite est de prendre le premier film comme référence et de positionner le deuxième film manuellement par rapport au premier.

    Une solution possible serait d'utiliser un timer pour vérifier la synchro à  intervalle régulier et de faire une rectification si un décalage est constasté.

    pour cela il faut connaà®tre la position des deux films:
    <br />// en langage C<br /><br />long getTime(Movie movie)<br />{<br />TimeRecord timeRecord;<br /><br />TimeValue time=GetMovieTime(movie,&amp;timeRecord);<br />TimeScale scale=GetMovieTimeScale(movie);<br /><br />// retourne la position en 100e de seconde<br /><br />return time/(scale/100);<br /><br />}<br /><br /><br />//pour fixer la position<br /><br />void setTime(Movie movie,long t)  // t en 100e de seconde<br />{<br />TimeScale scale=GetMovieTimeScale(movie);<br />Timevalue time=t*scale/100;<br /><br />SetMovieTimeValue(movie,time);<br /><br />}<br />
    


    Pour programmer un timer c'est ICI
  • ZyrolZyrol Membre
    15:05 modifié #6
    Ok
    Mais avant de me lancer dans les timer, j'ai une question à  te poser :
    je vais ensuite implementer une fonction pour définir un point d'entrée différent sur les 2 vidéos afin de lancer la lecture à  partir du point de lecture des 2 vidéos. Est ce que le timer ne gênera pas ce fonctionnement ?

  • mpergandmpergand Membre
    15:05 modifié #7
    Dans ce cas il faut maintenir le même décalage entre les deux vidéos, donc on ne teste pas l'égalité time1=time2 mais time1 +- delta=time2;
  • ZyrolZyrol Membre
    15:05 modifié #8
    Merci pour ces éclaircissements....
    mais étant débutant dans la programmation sous objective-c, je n'arrive pas à  déclarer et utiliser ta première fonction getTime.

    Peux tu m'éclairer un peu ?
    merci
  • mpergandmpergand Membre
    15:05 modifié #9
    Tu peux regrouper toutes les fonctions C quicktime dans un fichier et faire un include du header dans ta classe ObjC.

    <br />#include &quot;fonctionsQT.h&quot;<br /><br /><br />-(long) movieTime: (*NSMovieView) movieView<br />{<br />Movie movie=[[movieView movie] QTMovie];<br /><br />return getTime(movie);<br /><br />}<br />
    



  • cbrandtcbrandt Membre
    15:05 modifié #10
    ses fonctions getTime et setTime doivent être déclarées/définies en dehors de tout classe objective-c (c'est à  dire après le @end si tu veux les mettre dans un .h et .m existant):

    .h:
    <br />@interface xyz<br />...<br />@end<br /><br />long getTime(Movie movie);<br />void setTime(Movie movie,long t);<br />
    


    de même pour le .m:
    <br />@implementation xyz<br />...<br />@end<br /><br />long getTime(Movie movie)<br />{<br />TimeRecord timeRecord;<br /><br />TimeValue time=GetMovieTime(movie,&amp;timeRecord);<br />TimeScale scale=GetMovieTimeScale(movie);<br /><br />// retourne la position en 100e de seconde<br /><br />return time/(scale/100);<br /><br />}<br /><br /><br />//pour fixer la position<br /><br />void setTime(Movie movie,long t)  // t en 100e de seconde<br />{<br />TimeScale scale=GetMovieTimeScale(movie);<br />Timevalue time=t*scale/100;<br /><br />SetMovieTimeValue(movie,time);<br /><br />}<br />
    
  • ZyrolZyrol Membre
    15:05 modifié #11
    j'ai pris l'option de déclarer apres le @end du .h et il me sort une erreur : " fatal error: method definition not in class context"

    Donc si j'ai bien compris ça ne lui plait pas parce que elle est en dehors du @end.

    comment faire ?
  • ZyrolZyrol Membre
    15:05 modifié #12
    voili,voilà ....
    //.h
    /* Controlleur */

    #import <Cocoa/Cocoa.h>

    @interface Controlleur : NSObject
    {
        IBOutlet id movieView1;
        IBOutlet id movieView2;
    IBOutlet id progress1;
    IBOutlet id progress2;
    IBOutlet id textFile1;
    IBOutlet id textFile2;
    IBOutlet id RAL_100;
    IBOutlet id RAL_75;
    IBOutlet id RAL_50;
    IBOutlet id RAL_25;
    IBOutlet id bar1;
    IBOutlet id dureeMovie1;
    IBOutlet id dureeMovie2;
    }
    - (IBAction)openMovie1:(id)sender;
    - (IBAction)openMovie2:(id)sender;
    - (IBAction)playMovie1:(id)sender;
    - (IBAction)playMovie2:(id)sender;
    - (IBAction)pauseMovie1:(id)sender;
    - (IBAction)pauseMovie2:(id)sender;
    - (IBAction)dualPlay:(id)sender;
    - (IBAction)dualPause:(id)sender;
    - (IBAction)pushRalenti:(id)sender;


    - (void)SetRalenti:(id)sender;

    @end


    //Fonction C

    - (long) getTime(Movie movie);
    - (void) setTime(Movie movie,long t);

  • mpergandmpergand Membre
    novembre 2004 modifié #13
    C'est du C:

    long getTime(Movie movie);
    void setTime(Movie movie,long t);


    -(long) c'est en objC
  • ZyrolZyrol Membre
    15:05 modifié #14
    Yes, merci.

    J'ai encore bataillé pendant un certain temps, mais je n'avais pas inclut la bibliothèque QuicKTime dans le .h (uniquement dans le .m)

    D'ailleurs, si je ne me trompe pas, je n'ai qu'à  l'inclure dans le .h, non ? je peux l'enlever du .m ?
  • ZyrolZyrol Membre
    décembre 2004 modifié #15
    ça y est, j'ai réussi à  combler ce fameux retard. Sans me servir d'un timer.

    J'ai fais des tests, et le retard se crée uniquement au moment ou on appuyait sur le bouton de mise en lecture double.
    donc j'ai plutôt pris l'option de tester juste après la mise en double lecture si il y avait un décalage. si oui il est immédiatement rattrapé.

    Les vidéos sont synchronisées sans probleme maintenant.

    Merci à  tous pour m'avoir aidé à  clore le "chapitre" de la synchro !

  • mpergandmpergand Membre
    15:05 modifié #16

    J'ai fais des tests, et le retard se crée uniquement au moment ou on appuyait sur le bouton de mise en lecture double.
    donc j'ai plutôt pris l'option de tester juste après la mise en double lecture si il y avait un décalage. si oui il est immédiatement rattrapé.


    Je n'étais pas sûr que ça marche. D'ailleurs je suis pas sûr de grand chose dans cette histoire, c'est plus du pifomètre ;D
  • ZyrolZyrol Membre
    15:05 modifié #17
    La fonction setTime et GetTime, m'a beaucoup aidé. et c'est sur que ça marche !

    Donc merci encore 
  • mpergandmpergand Membre
    15:05 modifié #18
    J'ai récupéré ton appli, au démarrage des deux vidéos c'est un peu le bazar et après effectivement ça à  l'air de se caler plutot bien.

    je pensais que ça serait plus dur à  faire :D
  • ZyrolZyrol Membre
    15:05 modifié #19
    Suivant les formats des vidéos, ce "bazar" est plus ou moins accentué. En tout c'est sur, ensuite c'est synchro.

    Je vais essayer d'améliorer l'appli en ajoutant un module de chronométrage qui va se déclencher au moment de la lecture. Et aussi une amélioration générale :
    -Indication quand un point d'entrée est défini.
    -Amélioration des menus
    -Esthétique
    -Glisser-déposer (pour l'instant ça marche mais il n'y a pas le petit plus qui s'affiche au moment du déplacement)

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