大华9系平台hls流的转发
前言
需要转发两种文件
m3u8索引,用于指定ts文件列表
ts文件,以.ts结尾,用于转发流
代码
#coding:utf-8 from flask import Flask, request, Response,redirect import requests app = Flask(__name__) import hashlib import json API_ENDPOINT = "/videoService/accounts/authorize" from flask_cors import * #添加跨域请求允许的头部字段 # 对当前这个flask 核心对象app添加access-control-origin的头部字段 # 对/下所有的url 允许所有的origins来访问 CORS(app, resources={r"/*": {"origins": "*"}}) def send_first_login_request(): # Prepare and send the first login request to the API endpoint url = "http://172.21.201.91:8314" + API_ENDPOINT # Replace "API_BASE_URL" with the actual base URL of the API payload = { "userName": "system", "clientType": "winpc", "ipAddress": "10.10.10.10" } headers = { "Content-Type": "application/json;charset=UTF-8" } response = requests.post(url, json=payload, headers=headers) return response.json() def calculate_signature(username, password, realm, random_key, encrypt_type, method): password_value_0 = encrypt(password, encrypt_type) password_value_1 = encrypt(username + password_value_0, encrypt_type) password_tmp = encrypt(password_value_1, encrypt_type) encrypted_password = encrypt(username + ":" + realm + ":" + password_tmp, encrypt_type) return encrypt(encrypted_password + ":" + random_key, encrypt_type) def send_second_login_request(username, signature, random_key, encrypt_type): # Prepare and send the second login request to the API endpoint url = "http://172.21.201.91:8314" + API_ENDPOINT # Replace "API_BASE_URL" with the actual base URL of the API payload = { "userName": username, "signature": signature, "randomKey": random_key, "encryptType": encrypt_type, "clientType": "winpc", "ipAddress": "10.10.10.10" } headers = { "Content-Type": "application/json;charset=UTF-8" } response = requests.post(url, json=payload, headers=headers) return response.json() def encrypt(input_string, encrypt_type): hashed = hashlib.new(encrypt_type, input_string.encode()).hexdigest() return hashed def get_hls_url(channel_id, token): # Prepare and send the request to get HLS URL base_url = "http://172.21.201.91:8314"# Replace with the actual base URL endpoint = "/videoService/realmonitor/uri" params = { "channelId": channel_id, "scheme": "HLS" } headers = { "X-Subject-Token": token } response = requests.get(base_url + endpoint, params=params, headers=headers).text return json.loads(response) def gethls(channelId): print(channelId) first_login_response = send_first_login_request() #print(first_login_response) # Extract response parameters realm = first_login_response["realm"] random_key = first_login_response["randomKey"] encrypt_type = first_login_response["encryptType"] method = first_login_response.get("method", "") # Step 2: Prepare second login request username = "system" password = "密码" # Replace with the actual password signature = calculate_signature(username, password, realm, random_key, encrypt_type, method) #print(signature) # Step 3: Send second login request second_login_response = send_second_login_request(username, signature, random_key, encrypt_type) #print(second_login_response) # Process second login response # Extract the "token", "userName", "userId", "lastLoginIp", and other required fields from the response JSON # and perform the necessary actions. # Example usage channel_id = channelId token = second_login_response['token'] #print(token) # Get HLS URL hls_url_response = get_hls_url(channel_id, token) #print(hls_url_response) # Extract the HLS URL hls_url = hls_url_response["url"] print("HLS URL:", hls_url.replace('10.8.13.3','172.21.201.91')) return hls_url.replace('10.8.13.3','172.21.201.91') #视频网政务网ip替换 def reverse_proxy(url): channelId=url print('url length:',len(url),'\n\n\n') target_url=gethls(channelId) #真实地址 #return redirect(target_url, code=301) response = requests.get(target_url) return response.text proxy_url = "http://172.21.201.91:8050" @app.route('/cam/realmonitor/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE']) def proxy_cam(path): url = f"{proxy_url}/cam/realmonitor/{path}" if str(request.args)=='ImmutableMultiDict([])': path=path[:-7] #通道编码/.m3u8 print('get camera ask') return(reverse_proxy(path)) print('get ts') headers = {key: value for key, value in request.headers if key != 'Host'} # 处理 GET, POST, PUT, DELETE 请求 if request.method == 'GET': response = requests.get(url, headers=headers, params=request.args, stream=True) # 将目标服务器的响应转发给客户端 headers = [(name, value) for name, value in response.raw.headers.items()] return Response(response.content, response.status_code, headers) if __name__ == '__main__': app.run(host='0.0.0.0', port=8000)