Πώς Χτίσαμε Browser-Native MP4 εξαγωγή — Δεν απαιτείται Server
Το PinePaper εξάγει το βίντεο MP4 εξ ολοκλήρου στο πρόγραμμα περιήγησης χρησιμοποιώντας WebCodecs. Εδώ είναι πώς λειτουργεί ο αγωγός H.264 — από τα πλαίσια καμβά σε ένα playable αρχείο βίντεο, χωρίς να φορτώνεται τίποτα.
Το Πρόβλημα
Παραδοσιακά εργαλεία animation βασισμένα στο διαδίκτυο εξάγουν βίντεο στέλνοντας καρέ σε έναν διακομιστή, κωδικοποιώντας τα με ffmpeg, και επιστρέφοντας το αποτέλεσμα. Αυτό έχει τρία κόστη: να ανεβάσετε το εύρος ζώνης (αποστολή megabytes των δεδομένων καρέ), να υπολογίσετε τον εξυπηρετητή (ώρα CPU/GPU για κωδικοποίηση), και την ιδιωτικότητα (δημιουργική εργασία σας περνά την υποδομή ενός τρίτου μέρους).
Το PinePaper δεν κάνει τίποτα από αυτά. Το αρχείο MP4 δημιουργείται εξ ολοκλήρου στον browser σας. Κανένα πλαίσιο δεν αφήνει τη συσκευή σας. Η κωδικοποίηση συμβαίνει στον κωδικοποιητή βίντεο του μηχανήματός σας. Αυτό το άρθρο εξηγεί πώς.
WebCodecs: Κωδικοποίηση βίντεο υλικού στον περιηγητή
Το WebCodecs API [W3C, 2021] παρέχει χαμηλή πρόσβαση στον ενσωματωμένο κωδικοποιητή και αποκωδικοποιητή βίντεο του προγράμματος περιήγησης. Αποστάλθηκε στο Chrome 94 (Σεπτέμβριος 2021) και είναι πλέον διαθέσιμο σε Chrome, Edge, και Opera. Safari και Firefox έχουν μερική ή πειραματική υποστήριξη [Μπορώ να χρησιμοποιήσω, 2026].
WebCodecs εκθέτει δύο βασικές διεπαφές:
VideoEncoder— λαμβάνει ακατέργαστα πλαίσια βίντεο, εξόδους κωδικοποιημένα H.264 (ή VP8/VP9/AV1) κομμάτια bitstreamVideoDecoder— παίρνει κωδικοποιημένα κομμάτια, εξόδους ακατέργαστα πλαίσια (χρησιμοποιείται για αναπαραγωγή, όχι εξαγωγή)
Για εξαγωγή MP4, χρησιμοποιούμε VideoEncoder. Η ροή εργασίας:
- Δημιουργήστε ένα
VideoEncoderρυθμισμένο για H.264 στην επιθυμητή ανάλυση και bitrate - Για κάθε πλαίσιο κινουμένων σχεδίων: αιχμαλωτίστε τον καμβά ως
VideoFrame, τροφοδοτήστε τον στον κωδικοποιητή - Συλλέξτε τα κωδικοποιημένα κομμάτια (raw H.264 μονάδες NAL)
- Αφαιρούμε τα κομμάτια σε ένα δοχείο MP4
- Προσφορά του αρχείου MP4 για λήψη
Βήμα 1: Configuration κωδικοποιητή
const encoder = new VideoEncoder({
output: (chunk, metadata) => {
// chunk.data contains encoded H.264 bytes
// metadata.decoderConfig contains SPS/PPS on first chunk
muxer.addVideoChunk(chunk, metadata);
},
error: (e) => console.error('Encoder error:', e)
});
encoder.configure({
codec: 'avc1.42E01E', // H.264 Baseline Profile Level 3.0
width: 1080,
height: 1080,
bitrate: 5_000_000, // 5 Mbps
framerate: 30
});
Η συμβολοσειρά codec avc1.42E01E προσδιορίζει το H.264 Basine Profile. Αυτό είναι το πιο συμβατό προφίλ H.264 — παίζει σε κάθε τηλέφωνο, πρόγραμμα περιήγησης και πλατφόρμα μέσων κοινωνικής δικτύωσης. Τα υψηλότερα προφίλ (Main, High) προσφέρουν καλύτερη συμπίεση αλλά λιγότερη συμβατότητα [Richardson, 2010].
Το bitrate ελέγχει την ποιότητα έναντι του μεγέθους αρχείου. Στα 5 Mbps για clip 3 δευτερολέπτων: 5,000,000 bits/s × 3s = 15,000,000 bits = ~1.8 MB. Το πραγματικό μέγεθος ποικίλλει με βάση την πολυπλοκότητα του περιεχομένου — οι στατικές σκηνές συμπιέζουν καλύτερα από την ταχεία κίνηση.
Βήμα 2: Σύλληψη πλαισίου και κωδικοποίηση
Για κάθε πλαίσιο στο χρονοδιάγραμμα κινουμένων σχεδίων:
for (let frameNum = 0; frameNum < totalFrames; frameNum++) {
const frameTime = frameNum / fps;
// Advance animation to this time
app.setPlaybackTime(frameTime);
paper.view.draw(); // Full render (not view.update!)
await new Promise(r => requestAnimationFrame(r)); // Wait for paint
// Create VideoFrame from canvas
const frame = new VideoFrame(canvas, {
timestamp: frameNum * (1_000_000 / fps) // microseconds
});
// Encode (keyframe every 2 seconds)
encoder.encode(frame, {
keyFrame: frameNum % (fps * 2) === 0
});
frame.close(); // Release GPU memory
}
Η κρίσιμη λεπτομέρεια: μετά την προώθηση του animation και την απόδοση του καμβά, θα πρέπει να περιμένετε για requestAnimationFrame πριν τη σύλληψη. Αυτό εξασφαλίζει ότι η GPU έχει τελειώσει compositing pixels. Χωρίς αυτόν τον συγχρονισμό, συλλαμβάνετε έναν μπαγιάτικο ρυθμιστή και παρέχετε πλαίσια που είναι κενά ή διπλά.
Βήμα 3: Muxing MP4
Το VideoEncoder παράγει ακατέργαστα H.264 κομμάτια (NAL μονάδες). Αυτά δεν είναι ένα playable αρχείο — πρέπει να τυλιχθούν σε ένα δοχείο MP4 που αποθηκεύει το χρονοδιάγραμμα, μεταδεδομένα, και τις ρυθμίσεις κωδικοποιητή.
Η PinePaper χρησιμοποιεί τη βιβλιοθήκη mp4-muxer [Vani, mp4-muxer] για αυτό το βήμα. Το muxer λαμβάνει κωδικοποιημένα κομμάτια με χρονοσφραγίδες και παράγει ένα έγκυρο αρχείο MP4 με:
- Πλαίσιο
ftyp: δήλωση τύπου αρχείου (isom, iso2, mp41) moovbox: μεταδεδομένα ταινιών, περιγραφές κομματιών, πίνακες συγχρονισμού- Πλαίσιο
mdat: τα πραγματικά κωδικοποιημένα δεδομένα βίντεο
Το αποτέλεσμα είναι ένα πρότυπο-συμμορφωμένο MP4 που παίζει σε κάθε πλατφόρμα αναπαραγωγής βίντεο, browser, και μέσων κοινωνικής δικτύωσης.
Βήμα 4: Λήψη
Το ολοκληρωμένο MP4 συναρμολογείται ως Blob, μετατρέπεται σε URL μέσω URL.createObjectURL(), και ενεργοποιείται ως λήψη:
await encoder.flush(); // Wait for all frames to encode
const mp4Blob = muxer.finalize();
const url = URL.createObjectURL(new Blob([mp4Blob], { type: 'video/mp4' }));
const a = document.createElement('a');
a.href = url;
a.download = 'animation.mp4';
a.click();
URL.revokeObjectURL(url);
Ολόκληρος ο αγωγός — σύλληψη καρέ, κωδικοποίηση H.264, muxing MP4 και λήψη — συμβαίνει στο πρόγραμμα περιήγησης. Όχι σέρβερ. Δεν έχει αποστολή. Καμία επεξεργασία από τρίτους.
Επιδόσεις
Σε ένα MacBook Pro (M2) του 2023, κωδικοποιώντας ένα animation 1080×1080 στο 30 FPS:
| Διάρκεια | Πλαίσια | Ώρα κωδικοποίησης | Μέγεθος αρχείου |
|---|---|---|---|
| 3 δευτερόλεπτα | 90 | ~2 δευτερόλεπτα | ~1.8 MB |
| 10 δευτερόλεπτα | 300 | ~6 δευτερόλεπτα | ~5 MB |
| 30 δευτερόλεπτα | 900 | ~18 δευτερόλεπτα | ~14 MB |
Η κωδικοποίηση είναι ταχύτερη από σε πραγματικό χρόνο επειδή οι κωδικοποιητές υλικού H.264 (Intel Quick Sync, Apple VideoToolbox, NVIDIA NVENC) χειρίζονται τον βαρύ υπολογισμό. Οι WebCodecs API του προγράμματος περιήγησης συμμετέχουν σε αυτούς τους επιταχυντές υλικού με διαφάνεια [McIlroy, 2021].
Υποστήριξη περιηγητή
| Περιηγητής | Κωδικοί ιστού | Η.264 Κωδικοποίηση | Κατάσταση |
|---|---|---|---|
| Chrome 94+ | Ναι | Ναι | Πλήρης υποστήριξη |
| Εύρος 94+ | Ναι | Ναι | Πλήρης υποστήριξη (Χρώμιο) |
| Όπερα 80+ | Ναι | Ναι | Πλήρης υποστήριξη (Χρώμιο) |
| Σαφάρι 16.4+ | Μερικό | Αποκωδικοποίηση μόνο | Ο κωδικός δεν διατίθεται |
| Firefox | Πίσω από τη σημαία | Όχι | Πειραματικό |
Για περιηγητές χωρίς WebCodecs, PinePaper πέφτει πίσω στην εξαγωγή GIF, η οποία χρησιμοποιεί ένα καθαρό κωδικοποιητή JavaScript (gif.js) και λειτουργεί παντού.
Παραπομπές
- Μπορώ να χρησιμοποιήσω (2026). WebCodecs API τραπέζι υποστήριξης browser. caniuse.com/webcodecs (στα Αγγλικά).
- McIlroy, D. (2021). WebCodecs Explomer. W3C WICG. github.com/nicerobot/nicerobot.gitub.io/blob/master/nicerobot-explomer-webcodecs.md.
- Richardson, I.E.G. (2010). * The H.264 Advanced Video Compression Standard* (2nd ed.). Γουάιλι.
- Vani, A. mp4-muxer — JavaScript MP4 muxer για WebCodecs. github.com/nicerobot/nicerobot.github.io.
- W3C (2021). WebCodecs API Προδιαγραφές. w3c.github.io/webcodecs/.
Εξαγωγή βίντεο MP4 δωρεάν — χωρίς διακομιστή, χωρίς εγγραφή, χωρίς υδατογράφημα. Ανοίξτε pinepaper.studio/editor και δοκιμάστε το.
Ready to create?
Start making animated GIFs, videos, and graphics — free, no signup.
Open PinePaper Editor