• 记录一次IIS部署webform请求调用python服务的异常处理


    需求

    需要做一个获取视频网站的后台服务接口,输入一个房间号,获取对应的直播URL,然后给客户端展示直播。

    效果图

    在这里插入图片描述
    选择平台,输入房间号,或许直播线路图
    在这里插入图片描述
    如果未开播的话,则会返回未开播

    体验地址 : http://116.205.247.142:8080/GetBrocastLiveUrl.html

    分析

    • 执行对应的python逻辑,输入房间号,返回直播URL
    • 创建对应的webform一般处理程序服务,需要用到C#执行python
    • 发布IIS,这里需要避免权限问题的坑

    对应代码

    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))
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92

    C#一般处理程序

    using System;
    using System.IO;
    using System.Web;
    
    namespace MonitorToolSystem
    {
        /// 
        /// GetBrocastLiveUrl 的摘要说明
        /// 
        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;
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    这里Python版本是3.9.6

    IIS设置避坑

    本地跑的好好的,但一旦发布IIS,就会碰到访问权限的问题,会报错System.ComponentModel.Win32Exception拒绝访问,首先IIS需要以管理员身份运行,其次在Web.config中配置管理员账户访问权限,在中配置

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

    然后发现不报访问权限的错了,但是process没有返回值,这就很蛋疼,前面用户权限的问题坑了我一晚上,在公司处理到11点还没搞定失望而归,今天又在公司白天解决了访问权限的问题,但却没有正确得到返回值,又是解决问题,后来发现应用程序池需要设置标识为LocalSystem,非常重要,然后就能正确运行了
    http://116.205.247.142:8080/GetBrocastLiveUrl.ashx?roomId=2171135
    在这里插入图片描述
    上图是房间号为2171135的直播间的直播线路地址,如果当前房间没有直播,就是返回一下值
    在这里插入图片描述

    结论

    有以上经验,我就能做一个直播平台的聚合app了,只要知道各个平台的房间号,就能做一个根据直播类型分类的超大聚合直播app,是不是很开心呢!

  • 相关阅读:
    每日一题-轮转数组
    Tessent Ijtag 第二章节 什么是ICL文件
    自控力前言
    甲方需求被公司明确指示不能做,身为公司项目经理,怎么处理?
    免费享受企业级安全:雷池社区版WAF,高效专业的Web安全的方案
    童装业务占比扩大,APS生产排产解决服装企业生产管理难题
    动捕设备推动舞蹈表演动作捕捉动画制作突破边界
    Vue+Echarts+API 实现折线图对农地温湿度采集功能
    自动售卖团餐:借助智享直播AI实景无人直播系统,团餐自动售卖,无需人工参与,省时高效。
    新能源汽车动态
  • 原文地址:https://blog.csdn.net/s10141303/article/details/126076254