打造個人多媒體服務器之二


打造個人多媒體服務器之二

背景:

我家里有台服務器存儲了好多的數據,N多的資源.主要是學習視頻. 有時候人不在家的時候就看不到了,這當然不能阻止我 學習(瞎折騰)的熱情, 而且還不能下載下來觀看,因為存儲和時間的關系. 最好還得能倍速播放. 反正一陣折騰后,可以美滋滋看視頻了.

相關架構:

  • 內網資料服務器:中國大內網之稱的 中國移動寬帶 [100m下行,20m上行] [移動贈送]
  • [備用]中專(轉發)服務器1: 阿里雲 5m那種學生機. [學生機 100多塊]
  • [主用]中國電信家用寬帶1條:500m下載,20m上傳. [親戚家閑置,]

技術/軟件:

流媒體服務器 Nginx+Nginx-rtmp-module

打洞或轉發 frp

跳轉電信寬帶中專 flask

服務器ip更新 Zabbix [因為之前搭建了zabbix,所以就用zabbix獲取ip好了]

上一部分:https://www.cnblogs.com/lovesKey/p/11027348.html

一個簡單的流程圖 (實在不會畫)

使用效果:

家用電信ip轉發 2m/s 的樣子,看視頻完全沒問題.而且還很爽!!!

阿里雲ip轉發 600k/s 的樣子,正常看也沒什么問題,有時候快進需要緩沖一小下. 而且播放視頻的時候把帶寬用盡了,影響到其它服務了. [學生機 一百多文一年,5M寬帶還是很便宜的呢.]

看圖:

客戶端使用

之前的問題: 如flv,mpeg編碼的mp4文件都沒辦法直接點擊播放的.(自己也不會寫前端播放器.)

現在實現是這樣的.(右鍵點擊鏈接就可以播放,而且其他視頻流文件也可調用vlc 很爽)

調用了 vlc 播放器

看可以播放了.

最贊的是 vlc幾乎可以播放所有格式的視頻了. 而且也可以Linux下使用的.

現在架構的簡述

服務端Nginx+frp(打洞轉發工具,把內外的服務器暴露到外網)

高可用:用flask來切換,阿里雲或家用電信寬帶轉發

客戶端火狐瀏覽器(Chrome也是可以的)+插件Open in VLC media player+vlc播放器

服務端相關的配置文件:

內網服務器:

兩個frpc服務需要管理,一個使用supervisord,一個使用systemd管理.

  • supervisor管理

supervisor配置文件(管理鏈接到電信ip的frpc服務)

vim /etc/supervisor/supervisord.conf

[program:frpc]
directory = /home/makeit/apps/frp_0.27.0_linux_amd64/
command = /home/makeit/apps/frp_0.27.0_linux_amd64/frpc -c /home/makeit/apps/frp_0.27.0_linux_amd64/frpc.ini
autostart = true
startsecs = 10
autorestart = true
startretries = 3
user = root
redirect_stderr = true
stdout_logfile_maxbytes = 20MB
stdout_logfile_backups = 20
stdout_logfile = /home/makeit/apps/frp_0.27.0_linux_amd64/frac.log

#用來動態重啟frpc服務. 因為家庭電信ip經常會有變化,當變化的時候需要修改frpc配置文件並重新啟動frpc服務是之可用.

[program:keepSV]
directory = /home/makeit/apps/
command = /usr/bin/python3 /home/makeit/apps/keepSV.py
autostart = true
startsecs = 10
autorestart = true
startretries = 3
user = root
redirect_stderr = true
stdout_logfile_maxbytes = 20MB
stdout_logfile_backups = 2
stdout_logfile = /home/makeit/apps/keepSV.log


  • systemd管理

vim /lib/systemd/system/frpc.service

[Unit]
Description=Frp Client Service
After=network.target

[Service]
Type=simple
User=root
Restart=on-failure
RestartSec=5s
ExecStart=/usr/bin/frpc -c /etc/frp/frpc.ini
ExecReload=/usr/bin/frpc reload -c /etc/frp/frpc.ini

[Install]
WantedBy=multi-user.target
                

vim /etc/frp/frpc.ini

[common]
server_addr = 阿里雲的ip
server_port = 9000

log_file = /var/logs/frpc.log

# trace, debug, info, warn, error
log_level = info

log_max_days = 3

# for authentication
token = 2019

[rtmp_udp]
type = udp
local_ip = 127.0.0.1
local_port = 1935
# if remote_port is 0, frps will assign a random port for you
remote_port = 1935

[testnginx]
# tcp | udp | http | https | stcp | xtcp, default is tcp
type = tcp
local_ip = 127.0.0.1
local_port = 8080
# true or false, if true, messages between frps and frpc will be encrypted, default is false
use_encryption = true
# if true, message will be compressed
use_compression = true
# remote port listen by frps
remote_port = 6088
# frps will load balancing connections for proxies in same group
#group = test_group
# group should have same group key
#group_key = 123456
# enable health check for the backend service, it support 'tcp' and 'http' now
# frpc will connect local service's port to detect it's healthy status
health_check_type = tcp
# health check connection timeout
health_check_timeout_s = 3
# if continuous failed in 3 times, the proxy will be removed from frps
health_check_max_failed = 3
# every 10 seconds will do a health check
health_check_interval_s = 10



frpc鏈接電信ip的配置文件

# [common] is integral section
[common]
# A literal address or host name for IPv6 must be enclosed
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"
server_addr = 電信ip
server_port = 8088

# if you want to connect frps by http proxy or socks5 proxy, you can set http_proxy here or in global environment variables
# it only works when protocol is tcp
# http_proxy = http://user:passwd@192.168.1.128:8080
# http_proxy = socks5://user:passwd@192.168.1.128:1080

# console or real logFile path like ./frpc.log
log_file = /var/logs/frpc.log

# trace, debug, info, warn, error
log_level = info

log_max_days = 3

# for authentication
token = 20192019

[rtmp_udp]
type = udp
local_ip = 127.0.0.1
local_port = 1935
# if remote_port is 0, frps will assign a random port for you
remote_port = 1935

[testnginx]
# tcp | udp | http | https | stcp | xtcp, default is tcp
type = tcp
local_ip = 127.0.0.1
local_port = 8080
# true or false, if true, messages between frps and frpc will be encrypted, default is false
use_encryption = true
# if true, message will be compressed
use_compression = true
# remote port listen by frps
remote_port = 6088
# frps will load balancing connections for proxies in same group
#group = test_group
# group should have same group key
#group_key = 123456
# enable health check for the backend service, it support 'tcp' and 'http' now
# frpc will connect local service's port to detect it's healthy status
health_check_type = tcp
# health check connection timeout
health_check_timeout_s = 3
# if continuous failed in 3 times, the proxy will be removed from frps
health_check_max_failed = 3
# every 10 seconds will do a health check
health_check_interval_s = 10

Nginx 部分配置文件 相關參考 https://www.cnblogs.com/lovesKey/p/11027348.html

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    gzip  on;

    server {
        listen       8080;
        server_name  localhost;

        charset utf8;

        #access_log  logs/host.access.log  main;

        location / {
            root   /mnt/s2t;
            autoindex on;
            auth_basic "needAuth";
            auth_basic_user_file /usr/local/nginx/conf/passwd.db;
            index  index.html index.htm;
        }


監視電信ip變動,將變動后的ip寫到frpc配置文件內后重啟frpc服務.
vim /home/makeit/apps/keepSV.py

#
# by:lvusyy
#
import json
import os
import time

import requests
import sys, argparse


class Zabbix_Api:
    def __init__(self):
        self.url = 'http://zabbix服務器ip/zabbix/api_jsonrpc.php'
        self.header = {"Content-Type": "application/json"}
        self.id = 1
        self.auth=self.user_login()

    def json_obj(self,method,auth=True,params={}):
        obj = {'jsonrpc': '2.0',
               'method': method,
               'params': params,
               'auth': auth,
               'id': self.id}
        if not auth:
            del obj["auth"]
        return obj

    def user_login(self):
        data=self.json_obj(method="user.login",auth=False, params={"user": "zabbix賬號", "password": "zabiix密碼"})
        return json.loads(requests.post(url=self.url, headers=self.header, data=json.dumps(data)).text)["result"]

    def get_host(self):
        data=self.json_obj(method="host.get",
            params={
                "output": ["hostid", "name"]
            },
            auth=self.auth)

        return json.loads(requests.post(url=self.url, headers=self.header, data=json.dumps(data)).text)

    def get_mem_total(self,hostid):
        data=self.json_obj(method="item.get",
            params={
                "output": "extend",
                "hostids": hostid,
                "search": {
                    "key_": "vm.memory.size[total]"
                }
            },
            auth=self.auth)
        return int(json.loads(requests.post(url=self.url, headers=self.header, data=json.dumps(data)).text)["result"][0]["lastvalue"])/1024/1024/1024

    def get_ip(self,hostid):
        data=self.json_obj(method="item.get",
            params={
                "output": "extend",
                "hostids": hostid,
                "search": {
                    "key_": "ip"
                }
            },
            auth=self.auth)
        return json.loads(requests.post(url=self.url, headers=self.header, data=json.dumps(data)).text)["result"][0]['lastvalue']



def getIP(sv,tgName=''):
    tgHostId = 0
    hosts = sv.get_host().get('result', {})
    for _host in hosts:
        if tgName in _host.get('name', ''):
            tgHostId = _host.get('hostid', 0)
            break
    return (sv.get_ip(tgHostId))  # '10269'



def changeConf():
    '修改配置文件,使用模板方式替換,替換后重啟frpc服務然后把新ip地址傳給阿里雲'
    confPach='/home/makeit/apps/frp_0.27.0_linux_amd64/frpc2.ini'
    os.system('cp '+confPach+' '+confPach.replace('frpc2','frpc'))
    os.system('sed -i  s/wutoon\.com/'+ip+'/g  /home/makeit/apps/frp_0.27.0_linux_amd64/frpc.ini')
    os.system('supervisorctl restart frpc')
    time.sleep(3) #sleep 3 s
    requests.get('http://flaskip:88/ip?ip='+ip) #when fail do nothing

ip='阿里雲的ip地址'
def keepSVOnline(sv,tgName):
    '保持服務可用'
    global ip

    while True:
        if ip not in getIP(sv,tgName):
            ip=getIP(sv,tgName)
            changeConf()

        time.sleep(8)


if __name__ == '__main__':
    sv=Zabbix_Api()
    tgName='pxcnnet'

    keepSVOnline(sv,tgName) #multi thread

阿里雲配置

flask服務 負責跳轉(高可用?)
flask 安裝 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple flask

#by:lvusyy
from flask import Flask
from flask import request
from flask import  redirect
app = Flask(__name__)
IP = '阿里雲服務器的ip.com'

@app.route('/')
def hello_world():
    return redirect("//"+IP+":6088")

@app.route('/ip')
def ip():
    global IP
    _ip=request.args.get('ip',default='',type=str)
    if _ip:
        IP=_ip
        return 'ok'
    return 'fail'

if __name__ == '__main__':
    app.run(host="0.0.0.0",port=88)

frps.ini

[common]
# A literal address or host name for IPv6 must be enclosed
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"
bind_addr = 0.0.0.0
bind_port = 9000

# udp port to help make udp hole to penetrate nat
bind_udp_port = 9001

# udp port used for kcp protocol, it can be same with 'bind_port'
# if not set, kcp is disabled in frps
kcp_bind_port = 9000
token = 2019 

#!/bin/bash
  #push ip temp fan data to zabbix,使用被動方式 zabbix服務端需要建立對應的采集器
test $(($RANDOM%2))   && zabbix_sender -c /etc/zabbix/zabbix_agentd.conf -k "ip" -o `curl -s ip.cip.cc`  &>/dev/null || zabbix_sender -c /etc/zabbix/zabbix_agentd.conf -k "ip" -o `curl -s iiip.co`  &>/dev/null
zabbix_sender -c /etc/zabbix/zabbix_agentd.conf -k "temp.cpu" -o $(sensors -u coretemp-isa-0000 |grep temp1_input:|cut -c 16-55) &>/dev/null
zabbix_sender -c /etc/zabbix/zabbix_agentd.conf -k "fan.cpu" -o  $(sensors |grep fan2 |awk '{print $2}') &>/dev/null

客戶端軟件下載和配置:

火狐瀏覽器下載地址:http://www.firefox.com.cn/

Open in VLC media player 插件地址:https://addons.mozilla.org/zh-CN/firefox/addon/open-in-vlc/

vlc播放下載地址:http://get.videolan.org/vlc/3.0.7.1/win64/vlc-3.0.7.1-win64.exe

Open in VLC media player 設置

​ 上面配置vlc路徑如果是默認安裝路徑就不用修改即可.

​ 調用組件下載:https://github.com/andy-portmen/native-client/releases


​ 到此所有操作都已經完成了. 找到一個鏈接點擊右鍵 open in vlc 就可調用vlc播放器播放了.

​ Linux用戶的話.其實Linux用戶都是大神.(不需要特殊說明, 解壓Linux.zip 運行install.sh即可.)

​ On Linux and Mac, you can define custom root directory by adding --custom-dir= to the installer script
​ Example: ./install.sh --custom-dir=~/Desktop/

enjoy!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM