1. 程式人生 > >用 Python+nginx+django 打造線上家庭影院

用 Python+nginx+django 打造線上家庭影院

我喜歡看電影,尤其是好的電影,我會看上三四遍,仔細感受電影帶給我的另一種人生體驗,不同時期,不同年齡段看相同的電影,體驗也會不一樣。比如你上學時期看周星馳的電影可能就僅看到了笑點,工作之年之後再看,也許你會覺得這蘊含著深刻的人生哲理。

以前下載的電影,放的到處都是,手機上,U 盤裡,平板,桌上型電腦,筆記本上都儲存有下載過的電影,而且有時候平板或手機空間不夠,就不得不刪除珍藏已久的電影,很是可惜。當要看電影時,一時卻找不到自己曾下載過的電影,於是又在網上搜索,但是隨著版權越來越被重視,看視訊都要會員,或者付費觀看(這一點是進步的,只有這樣才會有更好的作品呈現。),沒有會員就要忍受非常煩人的廣告,而且未必是高清資源。想想曾經下載過的電影刪除了,現在看可能要收費了,很是遺憾。

如果電影可以統一放在廉價的桌上型電腦硬碟上,再開啟一個視訊流伺服器能讓所有的聯網裝置直接線上播放就好了,這樣就不用擔心下載過的電影無法找到了,而且覺得好的電影可以隨時推薦給家人和朋友觀看。

我知道 Python 是可以幹這個事情的,說幹就幹,當天晚上就做好了一個 demo。【如果你也有個想法想實現,那麼請即刻行動起來,如果超過 72 個小時還沒行動,你很可能再也不會去做了】

技術棧:python、django、nginx

感興趣的和我一起動手做吧。以 windows 作業系統為例,其他系統可做參考。

1、下載並配置 nginx

nginx 是什麼?

Nginx (“engine x”) 是一款是由俄羅斯的程式設計師 Igor Sysoev 所開發高效能的 Web 和反向代理伺服器,也是一個 IMAP/POP3/SMTP 代理伺服器。在高連線併發的情況下,Nginx 是 Apache 伺服器不錯的替代品。

這裡主要用 nginx 將 mp4 檔案轉化為流媒體,這樣就可以直接在網頁上播放 mp4 格式的電影,只需要簡單的配置即可,不需要編寫程式碼,非常簡單。

登陸官網下載 nginx:https://nginx.org/en/download.html,下載如下圖所示的穩定版本,解壓即可使用。
nginx-download.png

修改 nginx.conf ,在 http 部分新增如下所示的部分。

    server {
        listen       8080;
        server_name  localhost;
        location /movie {
            autoindex on;
            autoindex_exact_size off; 
            autoindex_localtime on;
            proxy_pass   http://127.0.0.1:8000/movie;
        }
        location ~ \.mp4{ 
              autoindex on;
              root  E:\\media;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

其中

        location ~ \.mp4{ 
              autoindex on;
              root  E:\\media;
        }

的作用是將 mp4 檔案轉化為流媒體的,只需要這一段,你就可以在瀏覽器上播放電影了,比如我在E:\media\ytza[迅雷下載Www.99b.Cc]伊甸湖BD1024高清中英雙字.mp4,我就可以在位址列按下圖所示的內容:
image.png

是不是有點小興奮。

但是,你不可能記得每一個電影名稱和路徑,nginx 雖然也可能列出檔案列表,但涉及到中文就會亂碼,而且不太容易解決,這就需要簡單的程式設計來解決檔案路徑顯示的問題。接下來看 2。

2、使用 Django 顯示本地電影列表

Django 是什麼,相信你會想起電影《被解救的姜戈》,Django 就是讀姜戈,第一個 D 不發音。
image.png

Python下有許多款不同的 Web 框架。Django 是重量級選手中最有代表性的一位。許多成功的網站和APP都基於 Django。Django 是一個開放原始碼的 Web 應用框架,由 Python 寫成。Django 遵守 BSD 版權,初次釋出於 2005 年 7 月, 並於 2008 年 9 月釋出了第一個正式版本 1.0 。Django 採用了 MVC 的軟體設計模式,即模型 M,檢視 V 和控制器 C。

Python 是什麼就不用介紹了,下面直接展示如何使用 django 快速生成一個網站。
在命令視窗依次執行下面的命令:

pip install django
django-admin startproject mysite
cd mysite
python manage.py startapp movie

1、編輯 movie 目錄下的 views 檔案如下所示:

from django.shortcuts import render
import os
# Create your views here.


FILE_HOME_DIR = "e:/media/"
MEDIA = [ ".mp4",]


def movie_list(request):
    next = request.GET.get("next", '')
    print(f"next = {next}")
    path = "/".join(request.path.split("/")[2:])
    print(f"request.path= {request.path}")
    print(f"path = {path}")

    #print os.listdir(FILE_HOME_DIR+".none/")
    data = {"files":[], "dirs":[]}
    print(data)
    child_path = FILE_HOME_DIR+path+next
    print(f"child_path = {child_path}")
    data['cur_dir'] = path+next
    print(data)
    for dir in os.listdir(child_path):
        if os.path.isfile(child_path+"/"+dir):
            if os.path.splitext(dir)[1] in MEDIA:
                data['files'].append(dir)
        else:
            data['dirs'].append(dir)

    print(data)
    return render(request,"movie/index.html", data)

2、在 movie 目錄下新建 templates/movie 資料夾,添到檔案 index.html,內容如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>電影列表</title>
</head>
<body>
<ul>
{% for dir in dirs%}
    <li style="color: #462921;font-size: 20px;">
        {{ dir }} <a  href="/movie/{{ cur_dir|safe }}/?next={{ dir|safe }}">進入</a>
    </li>
{% endfor %}
{% for file in files%}
    <li style="margin-right: 20px;font-size: 20px;">
         {{ file }} <button><a href="/{{ cur_dir|safe }}/{{ file|safe }}" target="_blank">播放</a></button>
    </li>
{% endfor %}
</ul>

</body>
</html>

3、修改 mysite/urls.py 內容如下:

from django.conf.urls import include,url
from django.contrib import admin

urlpatterns = [
    url(r'^polls/', include('polls.urls')),
    url(r'^movie/', include('movie.urls')),
    url(r'^admin/', admin.site.urls),
]

4、在movie 資料夾下新增 urls.py 內容如下:

from django.conf.urls import include,url
from . import views
app_name = 'movie'
urlpatterns = [
    url(r'', views.movie_list, name="movie"),
]

5、修改 settings.py 下列內容的值

INSTALLED_APPS = [
    'movie.apps.MovieConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
ALLOWED_HOSTS = ['*']

上述步驟對應的檔案如下圖所示:
image.png
其他保持預設即可。
接著在 manage.py 所在的資料夾內,也就是 mysite 目錄內執行

python manage.py makemigrations
python manage.py migrate
python manage.py runserver 0.0.0.0:8000

即可啟動會顯示電影列表的網站,如下圖所示:
image.png

此時 nginx 的這段程式碼就發揮作用了

        location /movie {
            autoindex on;
            autoindex_exact_size off; 
            autoindex_localtime on;
            proxy_pass   http://127.0.0.1:8000/movie;
        }

只要輸入 127.0.0.1:8080/movie 就會自動轉到 http://127.0.0.1:8000/movie 的服務上,這樣你就看到了電影的目錄,當點選對應的 mp4 檔案時,nginx 自動轉成流媒體為你播放。

在別的終端上看時,直接輸入伺服器所在的 IP 地址即可,如下圖所示:

進入目錄

image.png

有同學可能會問了,如果電影不是 mp4 格式的呢? 由於 html5 僅支援直接播放 mp4 ,我想到的辦法就是使用 ffmpeg.exe 將其他非 mp4 格式的電影轉成 mp4,程式碼已經為你寫好了,直接使用即可。
movie2mp4.py

# -*- coding: utf-8 -*-
#!/usr/local/bin/python
# Time: 2017/8/30 22:17:47
# Description:
# File Name: movie2mp4.py

import os
import subprocess
import time
import logging


logger = logging.getLogger()
logger.setLevel(logging.INFO)
ch = logging.StreamHandler()
fh = logging.FileHandler(filename="./convert.log")
formatter = logging.Formatter(
    "%(asctime)s - %(name)s - line:%(lineno)d - %(levelname)s - %(message)s"
)
fh.setFormatter(formatter)
ch.setFormatter(formatter)
logger.addHandler(ch)  # 將日誌輸出至螢幕
logger.addHandler(fh)  # 將日誌輸出至檔案

movie_path = r"e:\media"
movie_type = [".mkv", ".rmvb", ".avi",".flv",".MKV", ".RMVB", ".AVI",".FLV"]

for root, dir, files in os.walk(movie_path):
    for file in files:
        # print(file)
        shotname, extension = os.path.splitext(file)
        # print(shotname,extension)
        source_name = os.path.join(root, file)
        target_name = os.path.join(root, f"{shotname}.mp4")
        if extension in movie_type and not os.path.exists(target_name):
            logger.info(f"{source_name} -> {target_name}")
            bin_path = (
                r"D:\program\ffmpeg-20170830-2b9fd15-win64-static\bin\ffmpeg.exe"
            )
            #command = f"{bin_path} -i {source_name} -strict -2 {target_name}"
            command = f"{bin_path} -i {source_name} -c:v copy -c:a copy {target_name}"
            logger.info(command)
            try:
                a = subprocess.run(command, shell=True)
                if a.returncode == 0:
                    logger.info("convert successful.")
                    b = subprocess.run(f"del {source_name}", shell=True)
                    if b.returncode == 0:
                        logger.info("delete source successful.")
            except Exception as e:
                logger.info(f"conver error :{e}")

這樣就可以愉快的享受自己搭建的家庭影院了。

##3、後續可優化的方向

1、加入電影分類,最好是自動分類。
2、加入許可權控制,家裡的小朋友只能看少兒宜的電影。
3、加入域名服務,可以在外網看家裡的電影。
由於時間有限,後續如果有時間再弄吧。

如有需要獲取原始碼,加微信公眾號 somenzz ,後臺回覆 “家庭影院” 獲取。

somenzz.png