Η επιτυχία και η υιοθέτηση οποιασδήποτε εφαρμογής ιστού σήμερα εξαρτάται σε μεγάλο βαθμό από την απόδοση, την ευελιξία και την ευκολία χρήσης.
Ειδικά στον σημερινό κόσμο ADHD, Οι χρήστες θα χάσουν γρήγορα την υπομονή τους με μια εφαρμογή εάν η φόρτωση της σελίδας της διαρκεί πολύ . Για εφαρμογές ιστού που πρέπει να υποστηρίζουν την επεξεργασία βίντεο - η οποία είναι εγγενώς υπολογιστική και εντατική με I / O - αυτή η πρόκληση είναι ιδιαίτερα έντονη. Ωστόσο, οι χρήστες γίνονται όλο και πιο απαιτητικοί, θέλουν τα βίντεό τους να είναι υψηλής ποιότητας και φορτώστε γρήγορα, ακόμη και αν εκτελείται σε smartphone ή tablet.
Οι χρήστες χάνουν επίσης ανοχή για εφαρμογές ιστού που δεν λειτουργούν στο πρόγραμμα περιήγησης ή τη συσκευή που προτιμούν ή που δεν υποστηρίζουν τη μορφή δεδομένων που χρειάζονται για φόρτωση ή εξαγωγή. Η ποικιλομορφία των μορφών βίντεο που πρέπει να υποστηρίζονται συνεπώς καθιστά επίσης δύσκολη την ενσωμάτωση της υποστήριξης βίντεο σε μια εφαρμογή ιστού.
Αυτή η ανάρτηση περιγράφει πώς αξιοποίησα αποτελεσματικά τις τεχνολογίες ανοιχτού κώδικα και τις υπηρεσίες που βασίζονται σε σύννεφο για να ενσωματώσω τις δυνατότητες βίντεο σε μια εφαρμογή ιστού που βασίζεται σε PHP.
Ήμουν μέλος μιας ομάδας που χρειάστηκε να αναπτύξει έναν ιστότοπο τύπου YouTube, όπου οι εγγεγραμμένοι χρήστες μπορούσαν να ανεβάσουν και να μοιραστούν τα βίντεό τους.
Το σύστημα χρειάστηκε για να επιτρέπει στους εγγεγραμμένους χρήστες να ανεβάζουν τα βίντεό τους σε μια ποικιλία υποστηριζόμενων μορφών, οι οποίες στη συνέχεια θα μετατραπούν σε κοινή μορφή (MP4). Χρειαζόμασταν επίσης να δημιουργήσουμε ένα σύνολο μικρογραφιών και ένα κολάζ εικόνας για χρήση στο πρόγραμμα αναπαραγωγής βίντεο για την εμφάνιση των καρέ σε μια γραμμή προόδου βίντεο.
Τα πράγματα περιπλέκθηκαν περαιτέρω από το γεγονός ότι οι απαιτήσεις των πελατών μας εμπόδισαν να χρησιμοποιήσουμε οποιοδήποτε διαθέσιμο CDN ή transcoding API, οπότε χρειαζόμασταν να αναπτύξουμε τη λύση μας από το μηδέν.
Δεδομένου ότι η ίδια η διαδικασία μεταφόρτωσης δεν έπρεπε να είναι συγκεκριμένη για βίντεο (χρειαζόμασταν μια εύκολη στη χρήση δυνατότητα μεταφόρτωσης αρχείων), ήταν λογικό να χρησιμοποιήσουμε μια υπάρχουσα λύση ανοιχτού κώδικα αντί να κυλήσουμε τη δική μας. Επιλέξαμε jQuery-File-Upload , κυρίως επειδή υποστήριζε δύο χαρακτηριστικά που ήταν απαραίτητα στην περίπτωσή μας. δηλαδή, μια γραμμή προόδου μεταφόρτωσης και κομμένες μεταφορτώσεις.
Μεταφόρτωση με κομμάτια μας επέτρεψε να επιτρέψουμε σε έναν χρήστη να ανεβάσει ένα αρχείο βίντεο σχεδόν οποιουδήποτε μεγέθους (ιδιαίτερα σημαντικό για την υποστήριξη αρχείων βίντεο σε ανάλυση HD). Με αυτήν την προσέγγιση, το αρχείο χωρίζεται σε πολλά 'κομμάτια' στο μπροστινό μέρος που προκαλεί ενέργεια μεταφόρτωσης με κάθε κομμάτι δεδομένων (μαζί με τα μεταδεδομένα για κάθε κομμάτι, όπως ο αριθμός κομματιών και το συνολικό μέγεθος αρχείου). Στη συνέχεια, το πλήρες αρχείο βίντεο επανασυναρμολογείται στο πίσω μέρος. Παρεμπιπτόντως, η συμπερίληψη του αριθμού κομματιών στα μεταδεδομένα αποδείχθηκε ιδιαίτερα σημαντική καθώς ορισμένα προγράμματα περιήγησης (όπως το Mobile Safari) έχουν την τάση να μεταδίδουν τα κομμάτια σε τυχαία σειρά.
Η επεξεργασία βίντεο μπορεί να είναι τόσο απλή όσο η λήψη καρέ όπως ακίνητες εικόνες, ή μπορεί να περιλαμβάνει πιο περίπλοκες λειτουργίες όπως βελτίωση εικόνας, σταθεροποίηση της ροής βίντεο και ούτω καθεξής. Στην περίπτωσή μας, οι μόνες απαιτήσεις επεξεργασίας βίντεο ήταν (α) εξαγωγή κωδικοποιητών βίντεο και άλλων βασικών μεταδεδομένων και (β) δημιουργία ενός συνόλου μικρογραφιών και ενός κολάζ εικόνας (που θα χρησιμοποιηθεί στο πρόγραμμα αναπαραγωγής βίντεο για την εμφάνιση των πλαισίων σε μια πρόοδο βίντεο μπαρ).
FFmpeg - μια ευρέως χρησιμοποιούμενη, δωρεάν διανομή, βιβλιοθήκη ανοιχτού κώδικα - ήταν εξαιρετικά χρήσιμη για την ικανοποίηση αυτών των απαιτήσεων. Το FFmpeg παρέχει μια ολοκληρωμένη λύση πολλαπλών πλατφορμών για εγγραφή, μετατροπή και ροή αρχείων ήχου και βίντεο. Μπορεί επίσης να χρησιμοποιηθεί για τη μετατροπή βίντεο και για απλή επεξεργασία (π.χ. περικοπή, κοπή, προσθήκη υδατογραφήματος κ.λπ.).
Για τους σκοπούς μας, μπορέσαμε να χρησιμοποιήσουμε το FFmpeg για να χωρίσουμε το βίντεο σε δέκα ενότητες και στη συνέχεια να τραβήξουμε μια μικρογραφία για κάθε ενότητα για να παρέχουμε την απαραίτητη λειτουργικότητα.
Δυστυχώς, ωστόσο, δεν υπάρχουν δεσμεύσεις γλώσσας PHP για τη βιβλιοθήκη FFmpeg. Ως αποτέλεσμα, ο μόνος τρόπος για να αξιοποιήσετε το FFmpeg από την PHP είναι να καλέσετε το δυαδικό από τη γραμμή εντολών χρησιμοποιώντας εντολές συστήματος. Υπάρχουν βασικά δύο τρόποι για να χρησιμοποιήσετε το FFmpeg στο PHP:
sudo apt-get install libav-tools
. Οι εντολές libav είναι συμβατές με το FFmpeg και avconv . Η PHP πρέπει να έχει πρόσβαση στη γραμμή εντολών στο ffmpeg/avconv
για να το χρησιμοποιήσετε μέσω προγραμματισμού.composer update 'php-ffmpeg/php-ffmpeg'
.Χρησιμοποιήσαμε το PHP-FFMpeg δεδομένου ότι παρέχει εύκολη πρόσβαση στη λειτουργικότητα FFmpeg που μας ενδιαφέρει. Για παράδειγμα, το FFProbe
class από αυτό το πακέτο σάς δίνει τη δυνατότητα να λαμβάνετε πληροφορίες σχετικά με κωδικοποιητές ή το μήκος ενός συγκεκριμένου αρχείου βίντεο ως εξής:
$ffprobe = FFMpegFFProbe::create(); $ffprobe ->format('/path/to/video/mp4') // extracts file informations ->get('duration');
Το FFmpeg διευκολύνει επίσης την αποθήκευση οποιουδήποτε καρέ βίντεο:
$ffmpeg = FFMpegFFMpeg::create(); $video = $ffmpeg->open('video.mpg'); $video ->frame(FFMpegCoordinateTimeCode::fromSeconds(10)) ->save('frame.jpg');
Υπάρχει πιο λεπτομερής δείγμα κώδικα εδώ .
Μια σημείωση προσοχής: Λόγω ορισμένων νόμων περί ευρεσιτεχνιών, δεν είναι δυνατή η επεξεργασία όλων των κωδικοποιητών από το FFmpeg και ορισμένες μορφές δεν υποστηρίζονται σωστά (ή πλήρως). Θυμάμαι να παλεύω πριν από μερικά χρόνια, για παράδειγμα, με το .3gp
μορφή όταν η υποστήριξη για τηλέφωνα με δυνατότητα ήταν απαραίτητη.
Αφού λάβουμε τους κωδικοποιητές και άλλα μεταδεδομένα ενός βίντεο, προωθούμε το βίντεο σε μια ουρά μετατροπής FIFO (first in first out). Η ουρά υλοποιήθηκε χρησιμοποιώντας ένα απλό σενάριο cron που επιλέγει έναν δεδομένο αριθμό μη επεξεργασμένων βίντεο κάθε φορά που εκτελείται και τα μεταδίδει σε ένα βοηθητικό πρόγραμμα μετατροπής (διαθέσιμο δείγμα πηγαίου κώδικα εδώ ).
Το βοηθητικό πρόγραμμα μετατροπής καλεί το FFMpeg να εκτελέσει τη μετατροπή και επισημαίνει ότι κάθε βίντεο έχει υποβληθεί σε επεξεργασία.
Αναπτύξαμε επίσης έναν απλό μηχανισμό εκτίμησης χρόνου αναμονής, ο οποίος υπολογίζει τον μέσο χρόνο μετατροπής 1 λεπτού βίντεο. Χρησιμοποιώντας αυτόν τον μέσο όρο, είμαστε σε θέση να υπολογίσουμε και να προβάλλουμε στον χρήστη τον εκτιμώμενο υπολειπόμενο χρόνο επεξεργασίας μετά την ολοκλήρωση της μεταφόρτωσης ενός βίντεο, με βάση τον αριθμό των λεπτών που απομένουν για επεξεργασία.
Ορισμένες παγκοσμίως αναγνωρισμένες μορφές (όπως JPEG και GIF) έχουν προκύψει για ακίνητες εικόνες που ουσιαστικά υποστηρίζονται από όλες τις συσκευές και το λογισμικό επεξεργασίας εικόνας. Παρόλο που ορισμένες μορφές βίντεο είναι πιο συνηθισμένες από άλλες, δεν έχει εμφανιστεί ακόμη μια τέτοια παγκοσμίως υποστηριζόμενη μορφή για βίντεο.
Στην περίπτωσή μας, εκτός από την ανάγκη μετατροπής από μια ποικιλία μορφών σε μία κοινή κοινή μορφή (MPEG-4), χρειαζόμασταν τα βίντεο μετατροπής για βελτιστοποίηση για ροή σε κινητές συσκευές.
Για μετατροπή μορφής βίντεο (τουλάχιστον για τις βραχυπρόθεσμες ανάγκες μας), χρησιμοποιώντας το cloud Ελαστικός κωδικοποιητής Amazon ήταν η καλύτερη διαθέσιμη επιλογή. Εκτός από τη γενική ευκολία χρήσης, η υπηρεσία transcoder φροντίζει για τη βελτιστοποίηση και όλες τις ρυθμίσεις κωδικοποίησης. Ευτυχώς, ένα AWS SDK για PHP είναι διαθέσιμο, γεγονός που απλοποιεί την επίκληση της υπηρεσίας από τον κωδικό PHP.
Σημείωση: Η χρήση μιας υπηρεσίας που βασίζεται σε σύννεφο όπως το Amazon Elastic Transcoder είναι υπέροχη αν θέλετε να ξεκινήσετε γρήγορα και να λειτουργείτε. Ωστόσο, λάβετε υπόψη ότι αυτή η επιλογή μπορεί να γίνει ακριβή για τον πελάτη σας, ειδικά εάν το επιχειρηματικό μοντέλο του ενδέχεται να απαιτεί εκτεταμένη χρήση μεγάλων βίντεο. Ένας άλλος παράγοντας που πρέπει να λάβετε υπόψη είναι ότι δεν πρέπει απαραίτητα να υποθέσετε ότι τα βίντεο ή το επιχειρηματικό μοντέλο του πελάτη σας θα είναι συμβατά με τους Όρους Παροχής Υπηρεσιών.
Η Amazon χρησιμοποιεί τα βασικά στοιχεία αποθήκευσης και υπολογισμού της, S3 (Απλή υπηρεσία αποθήκευσης) και EC2 (Ελαστικό Compute Cloud) - συνδυασμένο με Αυτόματη κλιμάκωση και SNS (Απλή υπηρεσία ειδοποιήσεων) - να παρέχει τη δυνατότητα κλιμάκωσης προς τα πάνω και προς τα κάτω σχεδόν στιγμιαία.
Εγκατάσταση του aws-sdk είναι απλή, αφού η Amazon διατηρεί ένα Συνθέτης -η δυνατότητα εγκατάστασης του πακέτου. Απλώς προσθέστε ”aws/aws-sdk-php': '2.*'
στο composer.json
αρχειοθετήστε και κάντε ένα composer update
.
Προφανώς, η πρόσβαση στο Amazon Elastic Transcoder απαιτεί λογαριασμό Amazon, οπότε θα πρέπει επίσης να το ρυθμίσετε εάν εσείς (ή ο πελάτης σας) δεν έχετε ήδη έναν.
Η χρήση της υπηρεσίας Amazon Elastic Transcoder συνεπάγεται την πρώτη μεταφόρτωση αρχείων βίντεο σε κατάλληλο κάδο στο S3. Στη συνέχεια, κάναμε την εργασία transcoder υπεύθυνη για την αποκωδικοποίηση και τη δημιουργία μικρογραφίας η οποία, μετά την ολοκλήρωση, δημοσιεύει ένα αίτημα HTTP στην καθορισμένη διεύθυνση. Αυτό απαιτεί κάποια διαμόρφωση στον πίνακα AWS, αλλά είναι αρκετά απλό και η Amazon παρέχει καλή τεκμηρίωση για το πώς να το κάνετε αυτό.
Μη διστάσετε να χρησιμοποιήσετε το πακέτο transcoder μας , που βοηθά στην απλοποίηση της ενσωμάτωσης για Συμφωνία 2 . Περιλαμβάνει μια περιγραφή χρήσης και προσφέρει έναν ελεγκτή για γρήγορη εφαρμογή μιας υπηρεσίας ειδοποίησης που αποστέλλεται από την Amazon για τη συλλογή πληροφοριών σχετικά με το επεξεργασμένο βίντεο. Ένα παράδειγμα χρήσης είναι διαθέσιμο εδώ .
Επιπλέον, είναι διαθέσιμο ένα παράδειγμα ελεγκτή που χειρίζεται τις ειδοποιήσεις του Amazon εδώ που εφαρμόζει επίσης επιβεβαίωση μιας διεύθυνσης συνδρομής. Η υπηρεσία θα δημοσιεύσει πρώτα τη διεύθυνση URL που θα επισκεφτεί για να επιβεβαιώσει ότι αυτός είναι έγκυρος δέκτης ειδοποιήσεων. Το μόνο που απαιτείται είναι να επισημάνετε το βίντεο ως επεξεργασμένο. Από τότε, μπορούμε να χρησιμοποιήσουμε το βίντεο με κωδικοποίηση που είναι αποθηκευμένο στο cloud.
Η ροή βίντεο είναι μια ικανότητα που απαιτεί υψηλή απόδοση: Οι προσδοκίες των χρηστών για συνεχή ροή είναι υψηλές και η ανοχή για τον λανθάνοντα χρόνο είναι εξαιρετικά χαμηλή. Αυτή η πρόκληση συχνά επιδεινώνεται από την ανάγκη ροής βίντεο σε πολλούς πελάτες ταυτόχρονα σε πραγματικό χρόνο.
Στην περίπτωσή μας, χρειαζόμασταν να υποστηρίξουμε κάθε χρήστη να μπορεί να δημιουργήσει το δικό του κανάλι βίντεο και να ξεκινήσει τη μετάδοση. Η λύση μας αποτελείται από τρία συστατικά:
Εκτός από το γεγονός ότι η τεχνολογία Video on Demand (VOD) εξακολουθεί να εξελίσσεται, ένα άλλο ζήτημα που αντιμετωπίσαμε ήταν ότι η πρόσβαση στην κάμερα δεν υποστηρίχθηκε καλά και προσέφερε μόνο σύνδεση P2P. Επίσης, στόχος μας ήταν να παρέχουμε διαδικτυακές εκπομπές για πολλαπλούς ταυτόχρονους χρήστες. Επιπλέον, υποστήριξη για το getUserMedia/Stream
Το API (παλαιότερα οραματιζόταν ως στοιχείο) δεν είναι συνεπές σε όλα τα σύγχρονα προγράμματα περιήγησης. Με βάση αυτούς τους παράγοντες, αποφάσισα να χρησιμοποιήσω την τεχνολογία Flash αφού ήταν πραγματικά η μόνη λογική επιλογή. Και οι δύο εφαρμογές (Dashboard και Viewer) υλοποιήθηκαν χρησιμοποιώντας Καλώδιο και ActionScript .
Για τη μηχανή ροής, χρησιμοποιήσαμε Γουόζα . Αν και υπάρχουν άλλες, μη εμπορικές λύσεις (όπως Κόκκινο5 , το οποίο διατίθεται στην αγορά ως ουσιαστικά αντικατάσταση dropin για το Wowza), στην περίπτωσή μας η υποστήριξη εμπορικών προϊόντων ήταν ένας σημαντικός παράγοντας. Επίσης, τουλάχιστον τη στιγμή που χτίσαμε το σύστημα, η Wowza προσέφερε καλύτερη τεκμηρίωση που ήταν ένα επιπλέον πλεονέκτημα. (Λάβετε υπόψη ότι μπορείτε να λάβετε δωρεάν μια δοκιμαστική έκδοση του Wowza για 30 ημέρες και υπάρχει επίσης η δοκιμαστική έκδοση του προγραμματιστή που μπορείτε να χρησιμοποιήσετε έως και 180 ημέρες. Ωστόσο, υπάρχουν ορισμένοι περιορισμοί. Η ροή μπορεί να λειτουργήσει μόνο για δύο πελάτες και υπάρχει όριο στον μέγιστο αριθμό συνδέσεων.)
Χρησιμοποιήσαμε την εφαρμογή LiveStream που παρέχεται με το Wowza. Για να το ρυθμίσετε, αφήστε το applications/app_name
άδειο και σε conf/app_name
αντιγράψτε το Application.xml
αρχείο από το conf
κατάλογος. Επεξεργαστείτε το αρχείο για να ρυθμίσετε την ενότητα ως εξής:
live ${com.wowza.wms.context.VHostConfigHome}/content ${com.wowza.wms.context.VHostConfigHome}/keys
Η βασική παράμετρος είναι live
το οποίο ορίζει ότι αυτή θα είναι μια ροή από μια ζωντανή ροή βίντεο (π.χ. μια κάμερα). Λάβετε υπόψη ότι μετά την επεξεργασία και την αποθήκευση αυτού του αρχείου, θα πρέπει να κάνετε επανεκκίνηση του Wowza.
Το Flash παρέχει ένα πλήρως ενσωματωμένο σύστημα για τη σύνδεση κάμερας και μικροφώνου σε διακομιστή ροής Wowza. Αυτό είναι ιδιαίτερα χρήσιμο αν η εμπειρία σας με ActionScript είναι περιορισμένο.
Η όλη εφαρμογή βασίζεται ουσιαστικά στην αλληλεπίδραση μεταξύ των ακόλουθων αντικειμένων:
Πρώτα, συνδέουμε τον διακομιστή ροής Wowza χρησιμοποιώντας την παρουσία NetConnection και στη συνέχεια επισυνάπτουμε το πρόγραμμα ακρόασης συμβάντων που θα ακούσει αλλαγές στην κατάσταση σύνδεσης δικτύου:
nc = new NetConnection(); nc.connect(serverAddress:string); nc.addEventListener( NetStatusEvent.NET_STATUS, // event type eNetStatus, // listener function false, // use capture? 0, // priority true // use weak reference? );
Ακολουθεί ένα μινιμαλιστικό παράδειγμα ενός ακροατή συμβάντων που συνδέει την κάμερα και το μικρόφωνο με τον διακομιστή ροής:
private function eNetStatus(e:NetStatusEvent):void { switch (e.info.code) { case 'NetConnection.Connect.Success': camera = Camera.getCamera(); mic = Microphone.getMicrophone(); ns = new NetStream(nc); ns.publish(streamName, 'live'); ns.attachCamera(camera); ns.attachAudio(mic); break; case 'NetConnection.Connect.Closed': // debug trace... display user message break; }
Ο κωδικός πελάτη είναι πολύ παρόμοιος, εκτός από το ότι εμφανίζουμε μόνο είσοδο βίντεο από την πλευρά του χρήστη. Αυτό γίνεται συνδέοντας τη ροή στο Video
αντικείμενο, όπως φαίνεται σε αυτό το απλό παράδειγμα:
if(event.info.code == 'NetConnection.Connect.Success') { ns = new NetStream(nc); ns.client = nsClient; ns.addEventListener(NetStatusEvent.NET_STATUS, nsClient.onNetStatus); ns.play(streamName); video = new Video(); addChild(video); // this will display video video.attachNetStream(ns); // connect NetStream to video }
Η ζωντανή ροή και το βίντεο αναμένεται να διαδραματίζουν ολοένα και πιο σημαντικό ρόλο σε εφαρμογές για κινητά και ιστούς. Είναι επομένως σημαντικό για προγραμματιστές ιστού να εξοικειωθείτε με τη διακωδικοποίηση βίντεο, την επεξεργασία και τη ροή. Πολλά εργαλεία, βιβλιοθήκες και υπηρεσίες υπάρχουν σήμερα για την ενσωμάτωση αυτών των δυνατοτήτων σε εφαρμογές Ιστού. Αυτό το άρθρο δείχνει πώς αξιοποιήσαμε και ενσωματώσαμε ορισμένες από αυτές τις τεχνολογίες για να δημιουργήσουμε επιτυχώς έναν βασικό ιστότοπο τύπου YouTube με σχετική ευκολία.