Comment puis-je diffuser de la video depuis un iPhone agissant comme server?

Je travaille sur une application pour iOS, où un iPhone doit diffuser en direct ses loggings de camera vers un autre iPhone (pour garder les choses simples, les deux sont dans le même réseau Wi-Fi).
La diffusion en continu devrait fonctionner sans une interconnection physique (par exemple, un server utilisé pour apather le stream vers les clients). En fait, l' iPhone d'logging devrait être le server qui sert l'autre iPhone (ou plus d'autres appareils iOS dans le réseau) avec le stream en direct.

Donc, ce que je dois faire est:

  1. Obtenez les images en direct de l'appareil photo
  2. Traitez ces données si nécessaire
  3. Envoyer image par image aux clients connectés ( TCP? )
  4. Recevoir les trames sur le client et les afficher en time réel

Ce que j'ai et ce que je suis coincé avec:

  1. J'ai déjà résolu le problème 1. J'utilise un AVCaptureSession qui AVCaptureSession constamment CMSampleBufferRef (trouvé ici ).

  2. Je ne suis pas encore sûr de ce que je dois faire avec le CMSampleBufferRef . Je sais comment le transformer en CGImage ou en UIImage (grâce au super blogpost 2 de Benjamin Loulier), mais je n'ai aucune idée de ce que je dois spécifiquement envoyer et si j'ai besoin d'encoder les frames d'une manière ou d'une autre.
    Comme mentionné par @jab dans la réponse liée ci-dessus ( ceci ), il est possible d'écrire ces échantillons dans un file avec un ou plusieurs AVAssetWriter . Mais encore une fois, il dit que ces extraits video de 5 secondes doivent être téléchargés sur un server qui en fait un file video streamable (et ce film peut ensuite être diffusé sur un appareil iOS par HTTP Live Streaming je suppose).

  3. Comme je l'ai déjà indiqué, mon application (c'est-à-dire le périphérique "server" de capture video) est connectée à un ou plusieurs clients et doit leur envoyer les images video en time réel.
    Une idée qui m'est venue à l'esprit est d'utiliser une simple connection TCP où le server envoie chaque boucle dans un format sérialisé aux clients connectés dans une boucle. Plus spécifiquement: quand une trame tamponnée est envoyée avec succès au client, le server prend l'image la plus récente comme la suivante à envoyer.
    Maintenant: est-ce la bonne idée de comment cela devrait fonctionner? Ou existe-t-il un autre protocole, qui convient beaucoup mieux à ce genre de tâche?
    Rappelez-vous: je veux restr simple (simple pour moi, c'est-à-dire, pour ne pas avoir besoin d'étudier trop de nouveaux aspects de programmation) et rapide. Je connais déjà certaines choses sur TCP, j'ai écrit des servers et des clients avec ça à l'école en C , donc je préfère appliquer les connaissances que j'ai maintenant à ce projet …

  4. Dernier point mais non le moindre, le client destinataire:
    J'imagine, si je vais vraiment utiliser une connection TCP , que sur le côté client je reçois image après image du server, cast le package d'octets lus dans le format utilisé ( CMSampleBuffer , CGImage , UIImage ) et juste l'affichent sur un CALayer ou UIImageView , non? L'effet d'un film sera obtenu en gardant constamment à jour cette vue de l'image.

S'il vous plaît donnez-moi quelques idées sur la façon d'atteindre cet objective. C'est très important, car cela fait partie de mon projet de fin d'études … Tout exemple de code est également apprécié 😉 Ou référez-vous simplement à un autre site, tutoriel, Stackoverflow-réponse, etc.

Si vous avez des questions à ce sujet, laissez un commentaire et je mettrai à jour le post.

  1. Ça a l'air OK?

  2. Les images video sont vraiment grandes. Vous allez avoir des problèmes de bande passante en streaming video d'un appareil à l'autre. Vous pouvez compresser les images au JPEG utilisant UIImageJPEGRepresentation partir d'un UIImage , mais cela coûte cher en termes de calcul sur le "server", et il se peut qu'elles ne soient pas suffisamment petites pour être diffusées correctement. Vous pouvez également réduire votre fréquence d'images et / ou votre résolution en UIImage images, en sous-échantillonnant les UIImage et en jouant avec les parameters de votre AVCaptureSession . Alternativement, vous pouvez envoyer de petites videos (5 secondes), compressées matériellement sur le server et beaucoup plus faciles à gérer en bande passante, mais cela vous laissera bien sûr un retard de 5 secondes dans votre stream.

  3. Si vous avez besoin d'iOS 7, je vous suggère d'essayer MultipeerConnectivity.framework . Ce n'est pas très difficile à mettre en place, et je crois qu'il prend en charge plusieurs clients. Utilisez certainement UDP plutôt que TCP si vous voulez rouler votre propre réseau – c'est une application de manuel pour UDP, et il a less de frais généraux.

  4. Image par image, il suffit de transformer les JPEG en UIImage s et d'utiliser UIImageView . Il y a un calcul important, mais je crois que vous serez toujours limité par la bande passante plutôt que par le processeur. Si vous envoyez des petites videos, vous pouvez utiliser MPMoviePlayerController . Il y aura probablement de petits problèmes entre chaque video car cela les «préparera» pour la lecture, ce qui nécessitera aussi 5,5 secondes pour lire chaque video de 5 secondes. Je ne reorderais pas d'utiliser HTTP Live Streaming, sauf si vous pouvez get un vrai server dans le mix quelque part. Ou vous pouvez utiliser un pipeline ffmpeg – nourrir des videos et afficher des images individuelles – si vous le pouvez / voulez comstackr ffmpeg pour iOS.

Faites-moi savoir si vous avez besoin d'éclaircissements sur l'un de ces points. C'est beaucoup de travail mais relativement simple.

Si vous avez besoin d'une solution standard, vous pouvez essayer des bibliothèques de diffusion en continu. Celui que j'ai expérimenté est anglophone en streaming lib . Fonctionne plutôt bien avec la sortie RTMP vers le server multimédia Wowza.