Tutoriel n° 9 : Introduction au framework MediaPlayer

Par Dorémi

Je vais expliquer ici le fonctionnement du framework MediaPlayer et plus précisément comment jouer une vidéo grâce à lui. En plus du framework MediaPlayer ce tuto permettra de se familiariser un peu plus avec Interface Builder. A la fin le résultat sera le suivant :

http://www.ipup.fr/forum/userimages/resultat.jpg

http://www.ipup.fr/forum/userimages/resultat2.jpg

1) Création du projet

Pour commencer ouvrez XCode et créez un nouveau projet de type « Window-Based Application ». Donnez-lui un nom, dans mon exemple je l’ai appelé « IntroWithVideo » car au départ j’essayais de créer une vidéo d’intro pour un futur jeu sur iPhone. D’ailleurs je vous déconseille d’utiliser MediaPlayer pour tout ce qui est animation ce n’est pas du tout adapté, j’expliquerai pourquoi un peu plus tard.

Après avoir créé le projet, faites un clic droit sur « Classes » puis « Add » et « New File ». Dans la section « Cocoa Touch » sélectionnez « UIViewControllerSubclass ». Cliquez sur « Next » et choisissez un nom pour votre contrôleur. Dans mon exemple je l’ai appelé « IntroViewController ».

Maintenant, il va falloir rajouter le framework MediaPlayer car il n’y est pas de base. Pour cela cliquez droit sur le dossier framework, puis sur « Add » et « Existing Frameworks … ». Si vous avez de la chance vous trouverez directement le framework « MediaPlayer.framework » dans ce dossier. Sinon si vous êtes comme moi et que vous avez fait une installation de base le framework se trouve ici :

– DD > Developer > Platforms > iPhoneOS.platform > Developer > SDKs > iPhoneOS2.2.1.sdk >
system > library > Frameworks

S’il n’est toujours pas là je vous invite à utiliser la p’tite loupe en haut à droite pour rechercher
« MediaPlayer.framework ».

A la fin, voila à quoi doit ressembler votre architecture :

http://www.ipup.fr/forum/userimages/Architecture-debut.jpg

Le but du tuto

Avant de commencer la suite du tuto, il est important de comprendre ce que nous allons faire. Nous aurons la base de notre programme dans le fichier AppDelegate. Il se chargera d’initialiser notre contrôleur et d’afficher notre vue. Notre contrôleur, lui, contiendra un objet qui lui permettra de lire une vidéo. Il devra pouvoir lire une vidéo et initialiser une vidéo. Ensuite, grâce à Interface Builder, nous rajouterons un bouton à la vue du contrôleur qui permettra de lancer la vidéo.

Voilà, maintenant on peut vraiment commencer …

2) On complète maintenant IntroViewController.h

Pour commencer en-dessous de l’import d’UIKit.h il faut rajouter l’import de MediaPlayer :

#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>

Ensuite nous rajoutons deux attributs à notre classe. Pour le premier il s’agit de l’objet qui va nous permettre de lire des vidéos. Le second sera le « flux » ou le « chemin » où se trouve le fichier vidéo.

MPMoviePlayerController *mMoviePlayer;
NSURL *mMovieURL;

On va maintenant déclarer deux méthodes, la première servira à initialiser notre vidéo et la seconde servira à la lancer. Voilà leurs déclarations :

-(void)initMoviePlayer;
-(IBAction)playMovie:(id)sender;

Comme vous pouvez le voir le type de retour de la seconde méthode est « IBAction ». C’est parce qu’il s’agit de la méthode que nous relierons avec Interface Builder à un bouton « Lancer la vidéo ! ».

Pour finir avec la déclaration de cette classe on va rajouter une propriété sur « mMovieURL », histoire de lui associer un getter et un setter :

@property (nonatomic, retain) NSURL *mMovieURL;

On en a terminé avec les déclarations, passons maintenant à l’implémentation de notre beau contrôleur …

3) Implémentation IntroViewController

C’est ici que les choses commencent à se corser, je vais enfin vous expliquer le fonctionnement de MediaPlayer. Pour commencer, à la suite de la ligne « @implementation IntroViewController », rajoutez un beau « @synthesize mMovieURL ». C’est ce qui permet de créer le getter et le setter de l’attribut « mMovieURL ». Ensuite supprimez tout le code qui se trouve dans le fichier mis à part les méthodes « (void)didReceiveMemoryWarning » et « (void)dealloc », ça fera un peu de vide.

Maintenant il nous faut implémenter les deux méthodes déclarées plus haut. On va commencer par la plus simple, celle qui lance la vidéo :

3.1) On implémente PlayMovie

-(IBAction)playMovie:(id)sender {
[mMoviePlayer play];
}

Il suffit simplement d’utiliser la méthode « play » de la classe MPMoviePlayerController pour lancer la vidéo. Evidemment ça ne marchera pas si la vidéo n’a pas été initialisée avant et que l’objet mMoviePlayer n’a pas été alloué. Je ne l’utilise pas dans mon tuto mais il existe aussi la méthode « stop » pour mettre la vidéo en pause. Je dis bien en pause car si vous faites un « stop » suivi d’un « start » la vidéo reprendra là où vous l’aviez stoppée.

Passons maintenant à la méthode d’initialisation. Elle se découpe grosso modo en trois parties.

3.2) On instancie mMoviePlayer

mMoviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:mMovieURL];

D’abord on alloue un objet de type « MPMoviePlayerController » grâce à la méthode de classe alloc. Ensuite on appelle la méthode « initWithContentURL » pour initialiser notre player vidéo avec la bonne vidéo. (mMovieURL correspond à l’attribut déclaré plus haut, il contient les informations concernant notre vidéo).

3.3) On initialise les paramètres de notre mMoviePlayer

mMoviePlayer.scalingMode = MPMovieScalingModeNone;
mMoviePlayer.movieControlMode = MPMovieControlModeHidden;
mMoviePlayer.backgroundColor = [UIColor blackColor];

MediaPlayer possède trois propriétés importantes qui permettent de personnaliser notre vidéo :

1. le type de scaling, il permet de modifier l’affichage de la vidéo (plein écran, bordure …).
Je vous laisse les tester, ils sont au nombre de 4 :
o MPMovieScalingModeNone
o MPMovieScalingModeAspectFit
o MPMovieScalingModeAspectFill
o MPMovieScalingModeFill
2. les différents contrôles possibles, il y en a 3 en tout :
o MPMovieControlModeDefault (permet à l’utilisateur de modifier le son et de
revenir en arrière pendant le visionnage de la vidéo)
o MPMovieControlModeVolumeOnly
o MPMovieControlModeHidden (permet seulement de visionner la vidéo,
l’utilisateur ne peut rien faire)
3. le fond d’écran
Permet de déterminer la couleur du fond de la vidéo. Par exemple si vous choisissez un
type de scaling « Fit » vous verrez la couleur du fond sur les bordures de votre vidéo. (Si
vous ne comprenez pas l’histoire du fond choisissez un type de scaling « Fit » avec une
couleur de fond autre que noir et vous comprendrez à la fin de quoi il s’agit).

3.4) Et en option on met en place un système de notifications

MediaPlayer met en place un système de notifications pour 3 évènements. Je vais d’abord commencer par expliquer ce qu’est une notification. Il s’agit d’une méthode qui est appelée lors d’un évènement. Par exemple il est possible de dire à MediaPlayer que lors de l’évènement « notre vidéo est terminée » il doit exécuter telle méthode. Il est donc possible de gérer 3 évènements :

1. La vidéo a terminé de se charger en mémoire
2. La vidéo a terminé sa lecture
3. Le mode de scaling de la vidéo a été modifié

Pour ces trois évènements il est possible d’exécuter une fonction. Pour commencer, voilà à quoi ressemble le code pour dire à MediaPlayer d’associer chacun des évènements à une méthode :

// Permet d’appeler la méthode moviePreloadDidFinish lorsque la vidéo aura terminée de se charger
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(moviePreloadDidFinish:)
name:MPMoviePlayerContentPreloadDidFinishNotification
object:nil];

// Permet d’appeler la méthode moviePlaybackDidFinish lorsque la vidéo sera terminée
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:mMoviePlayer];

// Register to receive a notification when the movie scaling mode has changed.
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(movieScalingModeDidChange:)
name:MPMoviePlayerScalingModeDidChangeNotification
object:mMoviePlayer];

Alors plus clairement et en prenant la première notification. Je vais commencer du bas vers le haut. Notre notification prend 4 arguments :
– Tout en bas « object:nil », il s’agit de l’objet qui sera passé en argument à la méthode appelée.
– Ensuite « name », là, il s’agit du nom de la notification pour que MediaPlayer sache de quel évènement il s’agit.
– Ensuite « selector » permet de choisir le nom de la méthode qui sera appelée. Ici il s’agit de «moviePreloadDidFinish: » .Mais vous pouvez l’appeler n’importe comment. Il faudra ensuite
implémenter cette méthode.
– Et en dernier (ou premier), on trouve le « addObserver ». Ici on lui assigne « self », c’est-à-dire notre contrôleur. C’est lui qui sera chargé d’appeler notre méthode lorsque l’évènement arrivera.

Comme vous pouvez le voir dans les deux dernières notifications je passe en argument notre
« mMoviePlayer ». Cela permet de pouvoir faire des traitements dessus dans la méthode appelée. Bref ensuite il faut déclarer les trois méthodes associées aux notifications de cette manière :

// Notification called when the movie finished preloading.
– (void) moviePreloadDidFinish:(NSNotification*)notification
{
}

// Notification called when the movie finished playing.
-(void) moviePlayBackDidFinish:(NSNotification*)notification
{
}

// Notification called when the movie scaling mode has changed.
-(void) movieScalingModeDidChange:(NSNotification*)notification
{
}

Pour le tuto je ne les ai pas remplies, je voulais juste vous en parler. Si cette partie sur les notifications n’a pas été très claire c’est qu’il vous manque des bases en ce qui concerne les notifications smile Donc je suppose qu’un tuto sur les notifications serait sympa, ou alors il faut se référer au site d’Apple mais c’est assez dur à avaler et à digérer.

4) Maintenant il faut s’occuper de l’appDelegate

Tout d’abord on va ajouter notre vidéo dans le dossier ressource. Pour ça, clic droit sur « Resources » puis « Add » puis « Existing Files … ». Votre fichier doit être d’un de ces formats :

– .mov
– .mp4
– .mpv
– .3gp

Passons maintenant à notre delegate. Pour le header ce n’est pas compliqué, il faut ajouter notre contrôleur en tant qu’attribut. Le mot clé « IBOutlet » permet de dire à notre classe que notre contrôleur est « géré » par Interface Builder :

#import <UIKit/UIKit.h>

@class IntroViewController;

@interface IntroWithVideoAppDelegate : NSObject <UIApplicationDelegate> {
IBOutlet UIWindow *window;
IBOutlet IntroViewController *introViewController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@end

N’oubliez pas la ligne suivante dans IntroWithVideoAppDelegate.m :

#import « IntroViewController.h »

Pour le fichier source il y a une petite difficulté dans la méthode « applicationDidFinishLaunching ». Voilà le code source :

– (void)applicationDidFinishLaunching:(UIApplication *)application {

// Override point for customization after application launch
NSBundle *bundle = [NSBundle mainBundle];
if (bundle)
{
NSString *moviePath = [bundle pathForResource:@ »Movie » ofType:@ »mov »];
if (moviePath)
{
introViewController.mMovieURL = [NSURL fileURLWithPath:moviePath];
//[mMovieURL retain];
}
}
[window addSubview: introViewController.view];
[window makeKeyAndVisible];

[introViewController initMoviePlayer];
}

Les premières lignes de code permettent de retrouver ma vidéo. La chaine de caractère « Movie » est le titre de ma vidéo et la chaine de caractère « mov » est le format de ma vidéo. Donc selon votre vidéo il faudra modifier ces champs. En fait si vous connaissez le chemin vers votre vidéo vous pouvez ne garder que les lignes suivantes où « moviePath » est le chemin vers votre vidéo :

introViewController.mMovieURL = [NSURL fileURLWithPath:moviePath];

[window addSubview: introViewController.view];
[window makeKeyAndVisible];

[introViewController initMoviePlayer];

Premièrement on initialise « mMovieURL » (qui est l’attribut de notre contrôleur qui contient les informations de notre vidéo). C’est la méthode « fileURLWithPath » qui permet d’initialiser notre attribut pour qu’il puisse contenir les informations nécessaires pour jouer la vidéo.

Ensuite on ajoute la vue de notre contrôleur dans la fenêtre principale et on lance l’initialisation de notre player vidéo. Et voilà c’est fini ! Enfin presque il ne manque plus qu’à aller modifier le fichier « MainWindow.xib » dans le dossier « Resources » grâce à interface builder.

N’oubliez pas d’inclure le fichier « IntroViewController.h » dans ce fichier source.

5) Et pour finir Interface Builder

Double cliquez sur notre « MainWindow.xib ». Dans le menu en haut ouvrez « Library » qui se trouve dans le menu « Tools ». Allez dans la section « Controllers » puis glissez un « View Controller » dans votre
« MainWindow.xib ». Vous devez obtenir ceci :

http://www.ipup.fr/forum/userimages/window1.jpg

Double cliquez sur l’icône du « View Controller ». Ensuite, de la même manière que pour le « View Controller », allez dans « Library » puis dans la section « Windows, Views & Bars ». Sélectionnez une « View » et faites la glisser dans le cadre de notre « View Controller » que vous venez d’afficher. Toujours de la même manière et cette fois dans la section « Inputs & Values » faites glisser un bouton (Round Rect Button) dans notre contrôleur. Vous pouvez fermer la « Library » nous n’en avons plus besoin.

Maintenant ouvrez l’ « inspector » qui se trouve dans le menu « Tools ». On va commencer par configurer notre « View Controller ». Cliquez sur la partie grisée de notre « View Controller », là où il y a une petite pile verte. Bon, dans notre inspector il y a 4 parties. Allez dans la 4ème (le rond avec un petit « i »). Dans le champ Class mettez le nom de la class de votre contrôleur. Si vous avez choisi le même que moi il s’agit de « IntroViewController ». Appuyer sur la touche entrée, normalement la méthode « playMovie » est apparue dans la liste en dessous. (Si la méthode n’apparait pas c’est qu’il y a certainement un problème de syntaxe dans vos fichiers, essayez de compiler pour corriger les erreurs).

Ensuite et toujours dans l’ « inspector » allez cette fois dans la seconde partie (le petit rond bleu avec une flèche blanche dedans). Reliez l’élément « view » à la « view » qu’on a posé sur le contrôleur. De même reliez l’action « playMovie » vers le bouton et choisissez « Touch Up Inside » dans la liste qui s’affiche. Et pour en finir avec les liens reliez un « New Referencing Outlet » à notre « Intro With Video App Delegate » comme le schéma suivant :

http://www.ipup.fr/forum/userimages/lien-appdelegate.jpg

Si vous sélectionnez votre vue (dans la fenêtre où se trouve le bouton) vous pouvez modifier la couleur d’arrière plan dans la première section de l’ « inspector ». Vous pouvez faire de la même manière pour le bouton.

Maintenant vous pouvez compiler et tout devrait fonctionner.

6) Quelques remarques

Dans la partie des notifications je passe en argument (object) mon attribut mMoviePlayer. C’est inutile car mes méthodes existent dans ma classe ou je peux accéder à cet attribut. Cela aurait pu être utile si les méthodes appelées venaient d’une autre classe.

J’initialise l’attribut mMoviePlayer du contrôleur dans le fichier source de l’application delegate. Ce serait mieux de faire une fonction d’initialisation dans notre contrôleur qui s’occupe de ça. En effet c’est plus logique que chaque classe initialise ses propres attributs.

Je pense que le framework MediaPlayer est bien pour visionner des vidéos. Pour créer des animations (qui pourraient boucler) il vaut mieux se tourner vers Quartz Composer (que je ne connais pas du tout pour le moment smile).

Pour finir et le plus important, la vidéo se lance lorsqu’on clique sur le bouton. Or, si vous avez lu la partie sur les notifications, il existe un évènement « Chargement de la vidéo terminée ».
En fait il faudrait être sur que notre vidéo est bien chargée avant de lancer la méthode « play ». Pour ça, il est possible par exemple de passer un boolean à « YES » lorsque MediaPlayer nous envoie l’évènement « La vidéo a terminé de se charger ». Ensuite on teste dans la fonction « playMovie » si le boolean est à « YES » et seulement s’il l’est on lance la vidéo.

Voila ce tutoriel se termine ici, merci d’y avoir prêté attention et à bientôt !