找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 48|回复: 0

[原码]虎牙直播收看器。任意直播源播放,不定期更新时,...

[复制链接]

2万

主题

128

回帖

10万

积分

管理员

积分
101038
发表于 2022-10-17 10:00:29 | 显示全部楼层 |阅读模式 IP:山东省青岛市 移动

登录后更精彩...O(∩_∩)O...

您需要 登录 才可以下载或查看,没有账号?立即注册

×
[原码]虎牙直播收看器。任意直播源播放,不定期更新时,请看置顶贴


1输入虎牙房间ID号,不是网址中的号.
2点解析
3如果主播在线,默认播放地址为蓝光4M. 或者可以自己选择其它CDN及清晰度
4 播放
5.全屏快捷键 F11 ,或Esc键退出全屏
6 URL栏可以直播输入其它直播源地址,直接进行播放
7 代码编写环境 win7x64  python3.8

获取房间ID



本软件运行中截图


打包后的下载,如下。因本代码调用三方程序VLC所以同时打包了该程序约139M,测试环境win7x64
下载:https://wwz.lanzoub.com/i0n8F0e0biqf 密码:52pj




代码如下


[Python] 纯文本查看 复制代码
# -*- coding:utf-8 -*-
# @FileName  :huya_live_read.py
# @ Author   :dltest@52pojie
import json
import tkinter as tk
import tkinter.font as tkFont
from tkinter import *
from tkinter import ttk
import requests
import re
import os, platform
# 设置VLC库路径,需在import vlc之前
# os.environ['PYTHON_VLC_MODULE_PATH'] = "./vlc-3.0.6"
import vlc
class Player:
    '''
        args:设置 options
    '''
 
    def __init__(self, *args):
        if args:
            instance = vlc.Instance(*args)
            self.media = instance.media_player_new()
        else:
            self.media = vlc.MediaPlayer()
 
    # 设置待播放的url地址或本地文件路径,每次调用都会重新加载资源
    def set_uri(self, uri):
        self.media.set_mrl(uri)
 
    # 播放 成功返回0,失败返回-1
    def play(self, path=None):
        if path:
            self.set_uri(path)
            return self.media.play()
        else:
            return self.media.play()
 
    # 暂停
    def pause(self):
        self.media.pause()
 
    # 恢复
    def resume(self):
        self.media.set_pause(0)
 
    # 停止
    def stop(self):
        self.media.stop()
 
    # 释放资源
    def release(self):
        return self.media.release()
 
    # 是否正在播放
    def is_playing(self):
        return self.media.is_playing()
 
    # 已播放时间,返回毫秒值
    def get_time(self):
        return self.media.get_time()
 
    # 拖动指定的毫秒值处播放。成功返回0,失败返回-1 (需要注意,只有当前多媒体格式或流媒体协议支持才会生效)
    def set_time(self, ms):
        return self.media.get_time()
 
    # 音视频总长度,返回毫秒值
    def get_length(self):
        return self.media.get_length()
 
    # 获取当前音量(0~100)
    def get_volume(self):
        return self.media.audio_get_volume()
 
    # 设置音量(0~100)
    def set_volume(self, volume):
        return self.media.audio_set_volume(volume)
 
    # 返回当前状态:正在播放;暂停中;其他
    def get_state(self):
        state = self.media.get_state()
        if state == vlc.State.Playing:
            return 1
        elif state == vlc.State.Paused:
            return 0
        else:
            return -1
 
    # 当前播放进度情况。返回0.0~1.0之间的浮点数
    def get_position(self):
        return self.media.get_position()
 
    # 拖动当前进度,传入0.0~1.0之间的浮点数(需要注意,只有当前多媒体格式或流媒体协议支持才会生效)
    def set_position(self, float_val):
        return self.media.set_position(float_val)
 
    # 获取当前文件播放速率
    def get_rate(self):
        return self.media.get_rate()
 
    # 设置播放速率(如:1.2,表示加速1.2倍播放)
    def set_rate(self, rate):
        return self.media.set_rate(rate)
 
    # 设置宽高比率(如"16:9","4:3")
    def set_ratio(self, ratio):
        self.media.video_set_scale(0)  # 必须设置为0,否则无法修改屏幕宽高
        self.media.video_set_aspect_ratio(ratio)
 
    # 设置窗口句柄
    def set_window(self, wm_id):
        if platform.system() == 'Windows':
            self.media.set_hwnd(wm_id)
        else:
            self.media.set_xwindow(wm_id)
 
    # 注册监听器
    def add_callback(self, event_type, callback):
        self.media.event_manager().event_attach(event_type, callback)
 
    # 移除监听器
    def remove_callback(self, event_type, callback):
        self.media.event_manager().event_detach(event_type, callback)
 
class App:
    def __init__(self, root):
        self.editdate = '2022/10/17'
        self.root =root
 
        self.initUI(root)
        self.initData()
        self.player = Player()
        self.create_video_view(self.GLineEdit_621.winfo_id())
        self.root.bind("<F11>",self.changescreen)
        self.root.bind("<Escape>",self.exitfullscreen)
 
    def initData(self):
        self.GLineEdit_621.insert(0,'请输入直播间的ID')
        self.vol =50
        self.flag= True
        self.headers = {'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148'}
        self.api_url = 'https://mp.huya.com/cache.php?m=Live&do=profileRoom&roomid='
 
    def initUI(self,root):
        #setting title
        root.title(f"虎牙直播收看器 {self.editdate}  dltest@52pojie")
        #setting window size
        width=1244
        height=744
        screenwidth = root.winfo_screenwidth()
        screenheight = root.winfo_screenheight()
        alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
        root.geometry(alignstr)
        # root.resizable(width=False, height=False)
 
 
        self.GLineEdit_621=tk.Entry(root)
        self.GLineEdit_621["borderwidth"] = "1px"
        ft = tkFont.Font(family='Times',size=10)
        self.GLineEdit_621["font"] = ft
        self.GLineEdit_621["fg"] = "#333333"
        self.GLineEdit_621["bg"] = "#393d49"
        self.GLineEdit_621["justify"] = "center"
        self.GLineEdit_621["text"] = "ve"
        self.w =1243
        self.h =705
        self.GLineEdit_621.place(x=0,y=0,width=self.w,height=self.h)
        self.GLineEdit_621.bind('<Double-Button-1>',self.changescreen)
 
        self.GListBox_294=ttk.Combobox(root)
        ft = tkFont.Font(family='Times',size=10)
        self.GListBox_294["font"] = ft
        self.GListBox_294["justify"] = "center"
        self.GListBox_294.place(x=600,y=710,width=103,height=30)
        self.GListBox_294.bind("<<ComboboxSelected>>", self.choose)
 
        self.GLabel_149=tk.Label(root)
        ft = tkFont.Font(family='Times',size=10)
        self.GLabel_149["font"] = ft
        self.GLabel_149["fg"] = "#333333"
        self.GLabel_149["justify"] = "center"
        self.GLabel_149["text"] = "直播间ID:"
        self.GLabel_149.place(x=10,y=710,width=67,height=30)
 
        self.GLineEdit_15=tk.Entry(root)
        self.GLineEdit_15["borderwidth"] = "1px"
        ft = tkFont.Font(family='Times',size=10)
        self.GLineEdit_15["font"] = ft
        self.GLineEdit_15["fg"] = "#333333"
        self.GLineEdit_15["justify"] = "center"
        self.GLineEdit_15["text"] = "room_id"
        self.GLineEdit_15["relief"] = "groove"
        self.GLineEdit_15.place(x=80,y=710,width=83,height=30)
 
        self.GButton_246=tk.Button(root)
        self.GButton_246["bg"] = "#f0f0f0"
        ft = tkFont.Font(family='Times',size=10)
        self.GButton_246["font"] = ft
        self.GButton_246["fg"] = "#000000"
        self.GButton_246["justify"] = "center"
        self.GButton_246["text"] = "解析"
        self.GButton_246["relief"] = "groove"
        self.GButton_246.place(x=170,y=710,width=67,height=30)
        self.GButton_246["command"] = self.GButton_246_command
 
        self.GLabel_158=tk.Label(root)
        ft = tkFont.Font(family='Times',size=10)
        self.GLabel_158["font"] = ft
        self.GLabel_158["fg"] = "#333333"
        self.GLabel_158["justify"] = "center"
        self.GLabel_158["text"] = "选择清晰度:"
        self.GLabel_158.place(x=530,y=710,width=78,height=30)
 
        self.GLineEdit_316=tk.Entry(root)
        self.GLineEdit_316["borderwidth"] = "1px"
        ft = tkFont.Font(family='Times',size=10)
        self.GLineEdit_316["font"] = ft
        self.GLineEdit_316["fg"] = "#333333"
        self.GLineEdit_316["justify"] = "center"
        self.GLineEdit_316["text"] = "real_url"
        self.GLineEdit_316["relief"] = "groove"
        self.GLineEdit_316.place(x=450,y=710,width=80,height=30)
 
        self.GButton_701=tk.Button(root)
        self.GButton_701["bg"] = "#f0f0f0"
        ft = tkFont.Font(family='Times',size=10)
        self.GButton_701["font"] = ft
        self.GButton_701["fg"] = "#000000"
        self.GButton_701["justify"] = "center"
        self.GButton_701["text"] = "►播 放"
        self.GButton_701["relief"] = "groove"
        self.GButton_701.place(x=710,y=710,width=66,height=30)
        self.GButton_701["command"] = self.GButton_701_command
 
        self.GButton_132=tk.Button(root)
        self.GButton_132["bg"] = "#f0f0f0"
        ft = tkFont.Font(family='Times',size=10)
        self.GButton_132["font"] = ft
        self.GButton_132["fg"] = "#000000"
        self.GButton_132["justify"] = "center"
        self.GButton_132["text"] = "▍▍暂停"
        self.GButton_132["relief"] = "groove"
        self.GButton_132.place(x=780,y=710,width=66,height=30)
        self.GButton_132["command"] = self.GButton_132_command
 
        self.GButton_492=tk.Button(root)
        self.GButton_492["bg"] = "#f0f0f0"
        ft = tkFont.Font(family='Times',size=10)
        self.GButton_492["font"] = ft
        self.GButton_492["fg"] = "#000000"
        self.GButton_492["justify"] = "center"
        self.GButton_492["text"] = "⬛ 停止"
        self.GButton_492["relief"] = "groove"
        self.GButton_492.place(x=850,y=710,width=66,height=30)
        self.GButton_492["command"] = self.GButton_492_command
 
        self.GButton_813=tk.Button(root)
        self.GButton_813["bg"] = "#f0f0f0"
        ft = tkFont.Font(family='Times',size=10)
        self.GButton_813["font"] = ft
        self.GButton_813["fg"] = "#000000"
        self.GButton_813["justify"] = "center"
        self.GButton_813["text"] = "音量 +"
        self.GButton_813["relief"] = "groove"
        self.GButton_813.place(x=940,y=710,width=66,height=30)
        self.GButton_813["command"] = self.GButton_813_command
 
        self.GButton_229=tk.Button(root)
        self.GButton_229["bg"] = "#f0f0f0"
        ft = tkFont.Font(family='Times',size=10)
        self.GButton_229["font"] = ft
        self.GButton_229["fg"] = "#000000"
        self.GButton_229["justify"] = "center"
        self.GButton_229["text"] = "音量 -"
        self.GButton_229["relief"] = "groove"
        self.GButton_229.place(x=1010,y=710,width=66,height=30)
        self.GButton_229["command"] = self.GButton_229_command
 
        self.GButton_316=tk.Button(root)
        self.GButton_316["bg"] = "#f0f0f0"
        ft = tkFont.Font(family='Times',size=10)
        self.GButton_316["font"] = ft
        self.GButton_316["fg"] = "#000000"
        self.GButton_316["justify"] = "center"
        self.GButton_316["text"] = "静 音"
        self.GButton_316["relief"] = "groove"
        self.GButton_316.place(x=1080,y=710,width=66,height=30)
        self.GButton_316["command"] = self.GButton_316_command
 
        self.GButton_275=tk.Button(root)
        self.GButton_275["bg"] = "#f0f0f0"
        ft = tkFont.Font(family='Times',size=10)
        self.GButton_275["font"] = ft
        self.GButton_275["fg"] = "#000000"
        self.GButton_275["justify"] = "center"
        self.GButton_275["text"] = "F11全屏"
        self.GButton_275["relief"] = "groove"
        self.GButton_275.place(x=1180,y=710,width=59,height=30)
        self.GButton_275["command"] = self.GButton_275_command
 
        self.GLineEdit_754=tk.Entry(root)
        self.GLineEdit_754["borderwidth"] = "1px"
        ft = tkFont.Font(family='Times',size=10)
        self.GLineEdit_754["font"] = ft
        self.GLineEdit_754["fg"] = "#333333"
        self.GLineEdit_754["justify"] = "center"
        self.GLineEdit_754["text"] = "zhubo_name"
        self.GLineEdit_754.place(x=290,y=710,width=153,height=30)
 
        self.GLabel_143=tk.Label(root)
        ft = tkFont.Font(family='Times',size=10)
        self.GLabel_143["font"] = ft
        self.GLabel_143["fg"] = "#333333"
        self.GLabel_143["justify"] = "center"
        self.GLabel_143["text"] = "主播名:"
        self.GLabel_143.place(x=240,y=710,width=57,height=30)
 
    def create_video_view(self,wid):
        self.player.set_window(wid)
 
    def choose(self,event):
        url = self.GListBox_294.get()
        self.GLineEdit_316.delete(0,'end')
        self.GLineEdit_316.insert(0,url.split('::')[1])
 
    #解析
    def GButton_246_command(self):
        self.GLineEdit_316.delete(0,'end')
        room_id = self.GLineEdit_15.get()
        if not room_id:
            return
        try:
            html = requests.get(self.api_url + room_id, headers=self.headers)
            data = json.loads(html.text)['data']
            nick = data['profileInfo']['nick']
            room_name = data['liveData']['roomName']
            liveStatus = data['liveStatus']
            print(f'{nick} {room_name} {liveStatus}')
        except:
            print('Room id is invalid!')
            self.GLineEdit_754.delete(0,'end')
            self.GLineEdit_754.insert(0,'房号错误!')
            return
        if liveStatus == "OFF":
            self.GLineEdit_754.delete(0,'end')
            self.GLineEdit_754.insert(0,f'未开播 {nick}')
            return f'{room_name} {nick} is offline'
        elif liveStatus == "REPLAY":
            self.GLineEdit_754.delete(0,'end')
            self.GLineEdit_754.insert(0,f'未开播 {nick}')
            return f'{room_name} {nick} is REPLAY'
 
        else:
            self.GLineEdit_754.delete(0,'end')
            self.GLineEdit_754.insert(0,f'【{nick}】{room_name}')
            stream_dict = data['stream']
            flv = stream_dict['flv']  # type: dict
            cdn = flv['multiLine']  # type: List
            rate = flv['rateArray']  # type: List
            supportable_resolution = {'原画': '', }
            for b in rate:
                supportable_resolution[b['sDisplayName']] = b['iBitRate']
            sort_dict = {}
            listbox = []
            for resolution, bitrate in supportable_resolution.items():
                url_list = []
                for i in cdn:
                    url = i['url'].replace('http://', 'https://')
                    url = url.replace(
                        'imgplus.flv', f'imgplus_{bitrate}.flv')
                    url_list.append(url)
                sort_dict[resolution] = url_list
            for resolution, url_list in sort_dict.items():
                count=0
                for i in url_list:
                    count += 1
                    listbox.append(f'【{resolution}】{count}::{i}')
        self.GListBox_294["values"] = listbox
        for i in listbox:
            if i.startswith('【蓝光4M】'):
                # self.GListBox_294.current(1)
                self.GListBox_294.set(i)
                self.GLineEdit_316.delete(0,'end')
                self.GLineEdit_316.insert(0,i.split('::')[1])
                break
        else:
            self.GListBox_294.current(1)
            self.GLineEdit_316.delete(0,'end')
            self.GLineEdit_316.insert(0,i.split('::')[1])
 
 
    def GButton_701_command(self): #►播 放
        url = self.GLineEdit_316.get().strip()
        if not url:
            return
        if self.player.get_state() == 0:
            self.player.resume()
        elif self.player.get_state() == 1:
            pass  # 播放新资源
            self.player.play(url)
        else:
            self.player.play(url)
 
 
    #暂停
    def GButton_132_command(self):
        self.player.pause()
 
    #停止
    def GButton_492_command(self):
        self.player.stop()
 
    #音量加
    def GButton_813_command(self):
        vol = self.player.get_volume()
        self.player.set_volume(vol+5)
 
    #音量减
    def GButton_229_command(self):
        vol = self.player.get_volume()
        self.player.set_volume(vol-5)
 
    #静音
    def GButton_316_command(self):
        vol = self.player.get_volume()
        if vol == 0:
            self.player.set_volume(self.vol)
        else:
            self.vol = self.player.get_volume()
            self.player.set_volume(0)
 
    #全屏
    def GButton_275_command(self):
        if  self.flag:
            self.root.attributes('-fullscreen',True)
            self.w, self.h = self.root.winfo_screenwidth(), self.root.winfo_screenheight()
            self.GLineEdit_621.place(x=0,y=0,width=self.w,height=self.h)
            self.GButton_492.place_forget()
            self.GLabel_149.place_forget()
            self.GLineEdit_15.place_forget()
            self.GButton_246.place_forget()
            self.GLabel_143.place_forget()
            self.GLineEdit_754.place_forget()
            self.GLineEdit_316.place_forget()
            self.GLabel_158.place_forget()
            self.GListBox_294.place_forget()
            self.GButton_701.place_forget()
            self.GButton_132.place_forget()
            self.GButton_492.place_forget()
            self.GButton_813.place_forget()
            self.GButton_229.place_forget()
            self.GButton_316.place_forget()
            self.GButton_275.place_forget()
 
        else:
            self.root.attributes('-fullscreen',False)
            # self.GLineEdit_621.place(x=0,y=0,width=self.w,height=self.h)
            self.GLineEdit_621.place(x=0,y=0,width=1243,height=705)
            self.GLabel_149.place(x=10,y=710,width=67,height=30)
            self.GLineEdit_15.place(x=80,y=710,width=83,height=30)
            self.GButton_246.place(x=170,y=710,width=67,height=30)
            self.GLabel_143.place(x=240,y=710,width=57,height=30)
            self.GLineEdit_754.place(x=290,y=710,width=153,height=30)
            self.GLineEdit_316.place(x=450,y=710,width=80,height=30)
            self.GLabel_158.place(x=530,y=710,width=78,height=30)
            self.GListBox_294.place(x=600,y=710,width=103,height=30)
            self.GButton_701.place(x=710,y=710,width=66,height=30)
            self.GButton_132.place(x=780,y=710,width=66,height=30)
            self.GButton_492.place(x=850,y=710,width=66,height=30)
            self.GButton_813.place(x=940,y=710,width=66,height=30)
            self.GButton_229.place(x=1010,y=710,width=66,height=30)
            self.GButton_316.place(x=1080,y=710,width=66,height=30)
            self.GButton_275.place(x=1180,y=710,width=59,height=30)
 
        self.flag = not self.flag
 
 
 
    def changescreen(self,event):
        self.GButton_275_command()
 
    def exitfullscreen(self,event):
        self.flag = True
        self.root.attributes('-fullscreen',False)
        self.GLineEdit_621.place(x=0,y=0,width=1243,height=705)
        self.GLabel_149.place(x=10,y=710,width=67,height=30)
        self.GLineEdit_15.place(x=80,y=710,width=83,height=30)
        self.GButton_246.place(x=170,y=710,width=67,height=30)
        self.GLabel_143.place(x=240,y=710,width=57,height=30)
        self.GLineEdit_754.place(x=290,y=710,width=153,height=30)
        self.GLineEdit_316.place(x=450,y=710,width=80,height=30)
        self.GLabel_158.place(x=530,y=710,width=78,height=30)
        self.GListBox_294.place(x=600,y=710,width=103,height=30)
        self.GButton_701.place(x=710,y=710,width=66,height=30)
        self.GButton_132.place(x=780,y=710,width=66,height=30)
        self.GButton_492.place(x=850,y=710,width=66,height=30)
        self.GButton_813.place(x=940,y=710,width=66,height=30)
        self.GButton_229.place(x=1010,y=710,width=66,height=30)
        self.GButton_316.place(x=1080,y=710,width=66,height=30)
        self.GButton_275.place(x=1180,y=710,width=59,height=30)
 
 
if __name__ == "__main__":
    root = tk.Tk()
    app = App(root)
    root.mainloop()





回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|IOTsec-Zone|在线工具|CTF WiKi|CTF平台汇总|CTF show|ctfhub|棱角安全|rutracker|攻防世界|php手册|peiqi文库|CyberChef|猫捉鱼铃|手机版|小黑屋|cn-sec|分享屋 ( 鲁ICP备2021028754号 )

GMT+8, 2024-4-24 20:02

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表