# Uploader des vidéos lourdes depuis React Native > Retour sur un proof of concept d'upload de vidéos volumineuses depuis React Native : compression via react-native-video-processing, upload multipart avec fetch, et un mini serveur Express/Multer pour tester. Date : 18/02/2019 Auteur : Aurélien N. Tags : React Native, Mobile, Node.js --- Un client nous demande si c'est faisable : filmer une vidéo d'une minute dans une app React Native, la compresser côté téléphone, et l'envoyer sur un serveur. La question n'est pas si c'est possible (ça l'est) mais si c'est fiable sur des fichiers de 50-200 Mo en 4G, et combien de temps ça prend. On a monté un proof of concept pour répondre. ## Le pipeline : pick, compress, upload L'app fait trois choses. L'utilisateur choisit une vidéo depuis sa galerie via `react-native-document-picker`. On compresse la vidéo avec `react-native-video-processing` (un wrapper autour d'AVAssetExportSession sur iOS). Et on uploade le résultat en multipart via `fetch`. ```javascript // Compression : 640x480, pas d'audio, bitrate adapté const = await VideoPlayer.compress(uri, ) ``` On cible 640x480 en sortie. Le `bitrateMultiplier` est proportionnel au ratio de réduction : plus on réduit la résolution, plus on peut baisser le bitrate sans perte visible. On coupe l'audio pour gagner encore 20-30% de taille. Une vidéo de 60 secondes filmée en 1080p (150 Mo) passe à 8-15 Mo après compression. C'est la différence entre "uploadable en 4G" et "l'utilisateur abandonne". Si la vidéo dépasse 60 secondes, on la tronque avant compression : ```javascript if (duration > 60 * 1000) { const trimmed = await VideoPlayer.trim(uri, ) uri = trimmed.source } ``` ## L'upload : un fetch et c'est tout L'upload lui-même est un POST multipart classique. React Native supporte `FormData` nativement, et `fetch` sait envoyer un fichier local via son URI : ```javascript async function uploadVideo(uri, remoteUrl) { const ext = mime.extension(mime.getType(uri)) || "mp4" const type = mime.getType(uri) || "video/mp4" const formData = new FormData() formData.append("video", { uri, name: `video.$`, type, }) return await fetch(remoteUrl, ) } ``` C'est simple. C'est aussi limité. Pas de progress bar (le `fetch` de React Native ne supporte pas `onUploadProgress`), pas de reprise en cas de coupure réseau, pas de chunking. Pour un fichier de 10 Mo en wifi, ça passe sans problème. Pour 50 Mo en 4G instable, c'est un pari. ## Le serveur de test : Express + Multer Pour tester sans monter un vrai backend, on a un mini serveur Express avec Multer : ```javascript const upload = multer() const app = express() app.use(morgan("short")) app.post("/upload", upload.single("video"), (req, res) => { const = req.file res.json() }) app.listen(3000) ``` Multer gère le parsing multipart et sauvegarde le fichier sur disque. On pointe l'app React Native sur l'IP locale de la machine de dev. Ça permet de vérifier que le fichier arrive entier, avec le bon MIME type et la bonne taille. ## Ce qu'on a appris La compression fait toute la différence. Sans elle, uploader une vidéo de 60 secondes en 1080p est irréaliste sur mobile. Avec, on tombe à des tailles gérables. Le ratio 10:1 qu'on obtient (150 Mo → 15 Mo) est suffisant pour la plupart des cas d'usage. Le `fetch` natif de React Native fonctionne pour l'upload multipart, mais il manque les progress events. Pour une vraie app, il faudrait passer par `XMLHttpRequest` (qui supporte `upload.onprogress`) ou une lib native dédiée. La compression vidéo côté iOS est rapide (quelques secondes pour une minute de vidéo). Côté Android, `react-native-video-processing` utilise FFmpeg sous le capot et c'est plus lent. On n'a pas eu le temps de finaliser l'intégration Android sur ce POC. Le POC a validé ce qu'on voulait : oui, on peut filmer, compresser et uploader une vidéo d'une minute en moins de 30 secondes au total (compression + upload wifi). En 4G, ça monte à 1-2 minutes selon la couverture. Le client a eu sa réponse.