Record an IIS deployment webform request call python service exception handling

need

It is necessary to create a background service interface for obtaining video websites, enter a room number, obtain the corresponding live URL, and then display the live broadcast to the client.

renderings

Get live URL tool

insert image description here
Select the platform, enter the room number, or the live broadcast route map
insert image description here
. If it is not broadcast, it will return not broadcast

Experience address: http://116.205.247.142:8080/GetBrocastLiveUrl.html

analyze

  • Execute the corresponding python logic, enter the room number, and return the live broadcast URL
  • To create the corresponding webform general handler service, you need to use C# to execute python
  • Publish IIS, here you need to avoid the pit of permission issues

corresponding code

Python

# 获取哔哩哔哩直播的真实流媒体地址,默认获取直播间提供的最高画质
# qn=150高清
# qn=250超清
# qn=400蓝光
# qn=10000原画
import requests

import argparse
parser = argparse.ArgumentParser(description='manual to this script')
parser.add_argument("--roomId", type=str, default="2171135", help='search roomId')
args = parser.parse_args()

class BiliBili:

    def __init__(self, rid):
        """
        有些地址无法在PotPlayer播放,建议换个播放器试试
        Args:
            rid:
        """
        rid = rid
        self.header = {
    
    
            'User-Agent': 'Mozilla/5.0 (iPod; CPU iPhone OS 14_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, '
                          'like Gecko) CriOS/87.0.4280.163 Mobile/15E148 Safari/604.1',
        }
        # 先获取直播状态和真实房间号
        r_url = 'https://api.live.bilibili.com/room/v1/Room/room_init'
        param = {
    
    
            'id': rid
        }
        with requests.Session() as self.s:
            res = self.s.get(r_url, headers=self.header, params=param).json()
        if res['msg'] == '直播间不存在':
            raise Exception(f'bilibili {
      
      rid} {
      
      res["msg"]}')
        live_status = res['data']['live_status']
        if live_status != 1:
            raise Exception(f'bilibili {
      
      rid} 未开播')
        self.real_room_id = res['data']['room_id']

    def get_real_url(self, current_qn: int = 10000) -> dict:
        url = 'https://api.live.bilibili.com/xlive/web-room/v2/index/getRoomPlayInfo'
        param = {
    
    
            'room_id': self.real_room_id,
            'protocol': '0,1',
            'format': '0,1,2',
            'codec': '0,1',
            'qn': current_qn,
            'platform': 'h5',
            'ptype': 8,
        }
        res = self.s.get(url, headers=self.header, params=param).json()
        stream_info = res['data']['playurl_info']['playurl']['stream']
        qn_max = 0

        for data in stream_info:
            accept_qn = data['format'][0]['codec'][0]['accept_qn']
            for qn in accept_qn:
                qn_max = qn if qn > qn_max else qn_max
        if qn_max != current_qn:
            param['qn'] = qn_max
            res = self.s.get(url, headers=self.header, params=param).json()
            stream_info = res['data']['playurl_info']['playurl']['stream']

        stream_urls = {
    
    }
        # flv流无法播放,暂修改成获取hls格式的流,
        for data in stream_info:
            format_name = data['format'][0]['format_name']
            if format_name == 'ts':
                base_url = data['format'][-1]['codec'][0]['base_url']
                url_info = data['format'][-1]['codec'][0]['url_info']
                for i, info in enumerate(url_info):
                    host = info['host']
                    extra = info['extra']
                    stream_urls[f'线路{
      
      i + 1}'] = f'{
      
      host}{
      
      base_url}{
      
      extra}'
                break
        return stream_urls


def get_real_url(rid):
    try:
        bilibili = BiliBili(rid)
        return bilibili.get_real_url()
    except Exception as e:
        print('Exception:', e)
        return False


if __name__ == '__main__':
    #r = input('请输入bilibili直播房间号:\n')
    print(args.roomId)
    print(get_real_url(args.roomId))

C# general handler

using System;
using System.IO;
using System.Web;

namespace MonitorToolSystem
{
    
    
    /// <summary>
    /// GetBrocastLiveUrl 的摘要说明
    /// </summary>
    public class GetBrocastLiveUrl : IHttpHandler
    {
    
    
        public void ProcessRequest(HttpContext context)
        {
    
    
            context.Response.ContentType = "text/plain";
            var roomId = context.Request["roomId"];
            //服务器跟PC的python地址
            string pyToolPath = @"C:\Users\Administrator\AppData\Local\Programs\Python\Python39\python.exe"; //c:\users\d00605132\appdata\local\programs\python\python39\python.exe
            //string pyToolPath = @"c:\users\d00605132\appdata\local\programs\python\python39\python.exe";
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Pythons/bilibiliModify.py"); ;//(因为我没放debug下,所以直接写的绝对路径,替换掉上面的路径了)
            string sArguments = path;
            if (!string.IsNullOrEmpty(roomId))
            {
    
    
                sArguments = sArguments + $" --roomId={
      
      roomId}";
            }
            p.StartInfo.FileName = pyToolPath;
            p.StartInfo.UseShellExecute = true;
            p.StartInfo.Arguments = sArguments;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = false;
            p.Start();
            while (!p.HasExited)
            {
    
    
                p.WaitForExit();
            }
            string output = p.StandardOutput.ReadToEnd();
            if (string.IsNullOrEmpty(output))
            {
    
    
                context.Response.Write($"error:沒有查询到房间数据");
            }
            else
            {
    
    
                context.Response.Write($"{
      
      output}");
            }
        }

        public bool IsReusable
        {
    
    
            get
            {
    
    
                return false;
            }
        }
    }
}

Here the Python version is 3.9.6

IIS settings to avoid pitfalls

It runs well locally, but once IIS is released, you will encounter access rights problems, and will report an error System.ComponentModel.Win32Exception to deny access. First, IIS needs to run as an administrator, and then configure administrator account access in Web.config Permissions, configured in <system.web>

<identity impersonate="true" userName="Administrator" password="xxx"/>

Then I found out that it was wrong not to report the access rights, but the process did not return a value, which was very painful. The problem of user rights in front of me was a problem all night. I was disappointed when I was in the company until 11:00. Today, I was in the company again During the day, I solved the problem of access rights, but did not get the return value correctly, and solved the problem again. Later, I found that the application pool needs to be identified as LocalSystem, which is very important, and then it can run correctly
http://116.205.247.142:8080 /GetBrocastLiveUrl.ashx?roomId=2171135
insert image description here
The picture above is the address of the live broadcast line of the live room with room number 2171135. If there is no live broadcast in the current room, it will return the following value
insert image description here

in conclusion

With the above experience, I can build an aggregation app for live broadcast platforms. As long as I know the room numbers of each platform, I can build a super-large aggregation live broadcast app classified according to the type of live broadcast. Isn’t it very happy!

Guess you like

Origin blog.csdn.net/s10141303/article/details/126076254