Dalam artikel ini, kita akan membahas cara membuat aplikasi sederhana yang memungkinkan kita untuk streaming video ke YouTube menggunakan Python, Flask, dan ffmpeg. Aplikasi ini akan memungkinkan pengguna untuk mengunggah video dan kemudian men-streaming-nya langsung ke platform YouTube melalui RTMP (Real-Time Messaging Protocol).
Persiapan Awal
Sebelum masuk ke penjelasan kode, pastikan Anda sudah memiliki beberapa software dan library berikut:
- Python 3.x: Pastikan Python sudah terinstall di komputer Anda.
- Pip: Pengelola paket Python, pastikan sudah ada dengan mengetik pip –version di terminal.
- ffmpeg: Digunakan untuk encoding dan streaming video. Untuk instalasi, Anda bisa mengunduh dari situs resmi ffmpeg dan ikuti instruksinya.
- Flask: Web framework yang kita gunakan untuk membuat server sederhana. Instal Flask dengan perintah:
pip install flask
- Threading: Digunakan untuk menjalankan streaming video dalam thread terpisah, agar proses server utama tidak terganggu.
Struktur Folder
Sebelum kita lanjutkan, buatlah struktur folder sederhana sebagai berikut:
project-folder/ │ ├── app.py ├── templates/ │ ├── base.html │ ├── index.html │ └── streams.html └── uploads/
Folder uploads/
akan digunakan untuk menyimpan file video yang diunggah. Folder templates/
akan berisi file HTML untuk tampilan web.
Penjelasan Kode app.py
Berikut adalah kode untuk file app.py
, yang merupakan server Flask dan logika utama aplikasi kita.
import threading import subprocess import os from flask import Flask, render_template, request, redirect, url_for, jsonify app = Flask(__name__) # Path to store uploaded videos UPLOAD_FOLDER = 'uploads/' app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER # Ensure the upload folder exists if not os.path.exists(UPLOAD_FOLDER): os.makedirs(UPLOAD_FOLDER) class CustomThread(threading.Thread): def __init__(self, thread_id, video_path, youtube_url, stop_event): threading.Thread.__init__(self) self.thread_id = thread_id self.video_path = video_path self.youtube_url = youtube_url self.stop_event = stop_event self.repeat = True def stream_to_youtube(self): # ffmpeg command to stream the video to YouTube video_path = self.video_path.replace('\\', '/') command = [ 'ffmpeg', '-re', # Read input at native frame rate '-i', video_path, # Input file '-c:v', 'libx264', # Video codec '-preset', 'veryfast', # Encoding speed '-maxrate', '3000k', # Max bitrate '-bufsize', '6000k', # Buffer size '-pix_fmt', 'yuv420p', # Pixel format '-g', '50', # Group of picture size (keyframes) '-c:a', 'aac', # Audio codec '-b:a', '160k', # Audio bitrate '-f', 'flv', # Output format for RTMP streaming self.youtube_url ] if self.repeat: command.insert(1, '-stream_loop') command.insert(2, '-1') # Start the ffmpeg process if subprocess.Popen(command): return True else: return False def run(self): self.stream_to_youtube() def stop(self): self.stop_event.set() stream_threads = [] @app.route('/') def index(): global stream_threads if len(stream_threads) > 0: print(stream_threads[0].thread_id) return render_template('index.html') @app.route('/upload', methods=['POST']) def upload_video(): global stream_threads # Get the uploaded video and stream key from the form video = request.files['video'] stream_key = request.form['stream_key'] if video and stream_key: # Save the uploaded video file video_path = os.path.join(app.config['UPLOAD_FOLDER'], video.filename).replace('\\', '/') video.save(video_path) # Stream the video to YouTube using the stream key youtube_url = f"rtmp://a.rtmp.youtube.com/live2/{stream_key}" # Start a new thread to stream the video stop_event = threading.Event() thread_id = len(stream_threads) + 1 stream_thread = CustomThread(thread_id, video_path, youtube_url, stop_event) stream_threads.append(stream_thread) stream_thread.run() return f"Video streaming to YouTube started with thread ID !" else: return "Please upload a video and provide a stream key." @app.route('/stop_all_streams', methods=['POST']) def stop_all_streams(): global stream_threads for stream_thread in stream_threads: stream_thread.stop() return "All streaming threads stopped!" # streams @app.route('/streams') def streams(): global stream_threads return render_template('streams.html', stream_threads=stream_threads) @app.route('/stop_stream/<int:thread_id>', methods=['POST']) def stop_stream(thread_id): global stream_threads for stream_thread in stream_threads: if stream_thread.thread_id == thread_id: stream_thread.stop() stream_threads.remove(stream_thread) return f"Stream {thread_id} stopped!" return f"Stream {thread_id} not found!" if __name__ == '__main__': app.run(debug=True)
Penjelasan Kode
- Library yang Digunakan:
- threading: Menjalankan proses streaming dalam thread terpisah.
- subprocess: Digunakan untuk menjalankan ffmpeg.
- os: Mengatur path dan file.
- flask: Framework untuk membuat server web.
- CustomThread: Kelas ini bertanggung jawab untuk menjalankan streaming video menggunakan ffmpeg. Kode ini memulai thread yang mengambil video dari path lokal dan mengirimkannya ke URL RTMP YouTube.
- Endpoint Utama:
- / (Homepage): Halaman utama untuk mengunggah video dan memulai stream.
- /upload: Endpoint untuk menangani unggahan video dan memulai streaming.
- /stop_all_streams: Endpoint untuk menghentikan semua stream yang sedang berjalan.
- /streams: Menampilkan semua stream yang sedang aktif.
- /stop_stream/<thread_id>: Menghentikan stream berdasarkan thread_id.
Tampilan HTML (Folder templates/)
base.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Video Streaming</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/admin-lte/3.1.0/css/adminlte.min.css"> <style> body { font-family: Arial, sans-serif; margin: 20px; } .container { margin-top: 20px; } </style> </head> <body> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <a class="navbar-brand" href="/">Video Streaming</a> </nav> <div class="container-fluid"> <div class="row"> <nav class="col-md-2 d-none d-md-block bg-light sidebar"> <div class="sidebar-sticky"> <ul class="nav flex-column"> <li class="nav-item"> <a class="nav-link" href="/">Stream to YouTube</a> </li> <li class="nav-item"> <a class="nav-link" href="/streams">Active Streams</a> </li> </ul> </div> </nav> </div> </div> <div class="container"> {% block content %}{% endblock %} </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/admin-lte/3.1.0/js/adminlte.min.js"></script> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> </body> </html>
index.html
{% extends 'base.html' %} {% block content %} <h1>Stream to YouTube</h1> <form action="{{ url_for('upload_video') }}" method="POST" enctype="multipart/form-data"> <label for="video">Upload Video:</label> <input type="file" name="video" id="video" required><br><br> <label for="stream_key">YouTube Stream Key:</label> <input type="text" name="stream_key" id="stream_key" required><br><br> <button type="submit">Start Streaming</button> </form> <hr> <h2>Active Streams</h2> <ul> {% for stream_id in streams %} <li>Stream ID: {{ stream_id }} <form action="/stop_stream/{{ stream_id }}" method="post" style="display:inline;"> <button type="submit">Stop Stream</button> </form> </li> {% else %} <li>No active streams.</li> {% endfor %} </ul> {% endblock %}
streams.html
{% extends "base.html" %} {% block content %} <h1>Active Streams</h1> {{ streams }} <ul> <!-- {% for stream_id in streams %} <li>Stream ID: {{ stream_id.thread_id }} <form action="/stop_stream/{{ stream_id.thread_id }}" method="post" style="display:inline;"> <button type="submit">Stop Stream</button> </form> </li> {% else %} <li>No active streams.</li> {% endfor %} --> </ul> <a href="/">Back to Home</a> {% endblock %}
Menjalankan Aplikasi
- Simpan file-file di atas ke dalam struktur folder yang telah dijelaskan.
- Buka terminal, navigasikan ke direktori proyek, dan jalankan server Flask dengan perintah:
python app.py
- Buka browser dan akses http://localhost:5000.
Dengan langkah-langkah di atas, aplikasi ini memungkinkan pengguna untuk mengunggah video dan men-streaming-nya ke YouTube secara langsung. Anda juga bisa melihat dan menghentikan stream aktif dari halaman yang telah disediakan.
Jika Anda ingin mengembangkan keterampilan dalam membuat aplikasi streaming yang profesional dan berfungsi penuh, bergabunglah dengan kelas premium Masterclass: Membangun Aplikasi Streaming YouTube dengan Python & Flask. Dalam kursus ini, Anda akan belajar langkah demi langkah cara membangun aplikasi streaming, mulai dari dasar hingga fitur lengkap, dengan pendekatan langsung dan praktis. Bimbingan dari instruktur ahli akan membantu Anda menguasai penggunaan Python, Flask, dan FFmpeg untuk menghasilkan video streaming berkualitas tinggi. Jangan lewatkan kesempatan untuk membawa keterampilan Anda ke level berikutnya! Klik di sini untuk informasi lebih lanjut dan pendaftaran.