python ffmpeg直播客户端

在这里插入图片描述

在这里插入图片描述

import PySimpleGUI as sg
import sys
import json
import os
import requests
import subprocess
import pygame.camera
import pyaudio
import psutil
import time


#当 运行地址 os.getcwd()
__DIR__ = os.getcwd();
# 登入页面
logo = sg.Image(__DIR__+"\\bin\\image\\100.png")
my_text = sg.Text('XXX-直播伴侣',key = '_text_', visible = True, font=('宋体', 12), size=(0, 1), pad=((165, 0), (10, 0)),justification='center')
#账户
member_title = sg.Text('账号:',pad=((110, 0), (35, 0)),font=('宋体', 12))
member_name = sg.InputText('',key='name',pad=((0, 0), (35, 0)), size=(25, 1))
#密码
pwd_title = sg.Text('密码:',pad=((110, 0), (10, 0)),font=('宋体', 12))
pwd_name = sg.InputText('',key='pwd', pad=((0, 0), (10, 0)), size=(25, 1),password_char='*')
#  弹框提示
# sg.SystemTray.notify('Notification Title', 'This is the notification` message')

hello_button = sg.Button(button_text="登入",        # 按钮显示文本
                   tooltip='登入账号',             # 鼠标滑到按钮时显示的文本
                   border_width=0,             # 按钮边框
                   size=(15, 1),              # 按钮的长度,高度
                   auto_size_button=True,      # 自否自适应
                   button_color=('black', 'white'),  # 按钮字体颜色, 按钮的背景色
                   font=('宋体', 12),        # 设置字体,大小
                   bind_return_key=False,    # 是否绑定按键
                   focus=True,              # 鼠标是否放置在此按钮上
                   pad=((175, 0), (20, 0)),    # 设置元素的间距 (左,右),(上,下)
                   # key='START-EXEC',       # 元素唯一标示
                   visible=True)
layout = [
[logo],
    [my_text],#提示语句
    [member_title,member_name],
    [pwd_title,pwd_name],
    [hello_button]
]
icon_ = __DIR__+"\\bin\\icon\\favicon.ico"
window = sg.Window('XXX-直播伴侣', layout,grab_anywhere=True,size=(500,340),icon=icon_)

API_URL = 'http://xxxxxxx.top/api/v1';#htt
HEADER_UR =  'lxxxxxx';
headers ={
"Accept":"*/*",
"Accept-Encoding":"gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9",
"Connection": "keep-alive",
"Content-Type": "application/json",
"Host": HEADER_UR,
# "Access-Token":"695s",
# "Origin": "http://pslv4.kvniaudbfiuve12123.xyz",
# "Referer": "http://pslv4.kvniaudbfiuve12123.xyz",
"Content-Type": "application/json"
}

# event

def get_audio_devices():
    p = pyaudio.PyAudio()
    devices = []
    for i in range(p.get_device_count()):
        # print(p.get_device_info_by_index(i).get('name'))
        devices.append(p.get_device_info_by_index(i))
    return devices

def get_audio_input_devices():
    devices = []
    for item in get_audio_devices():
        if item.get('maxInputChannels') > 0:
            devices.append(item)
    return devices


def kill_process(pid):
    parent_proc = psutil.Process(pid)
    for child_proc in parent_proc.children(recursive=True):
        child_proc.kill()
    parent_proc.kill()



#获取音频设备
Audio_List =[];
# Audio_ =pyaudio.PyAudio()
# print(Audio_.get_default_output_device_info())
# for Audio_id in get_audio_input_devices():
# 	Audio_List.append(Audio_id.get('name'))

# print(Audio_List) -hide_banner -list_devices  true -f dshow -i 0
cmd = __DIR__+'\\bin\\ffmpeg  -list_devices true -f dshow -i dummy'#['ffmpeg', '-list_devices','true', '-f','dshow','-i','dummy']
process = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding="utf-8",text=True)
record = False
num_line = 0;
for line in process.stdout:
    # print(',,,,,', num_line)
    # print(line)
    if record:
        if line.startswith("[dshow"):
            _line = line[index + 2:]
            if _line.startswith("DirectShow audio"):
                record = False
            if record and num_line%2 == 0:
                Audio_List.append(_line[2:len(_line)-2])
            num_line+=1

    if line.startswith("[dshow"):
        index = line.find("]");
        if index > 0:
            _line = line[index+2:]
            if _line.startswith("DirectShow audio"):
                # print('>>>>>>>', _line)
                num_line = 0
                record = True


while True:
    event, value = window.read()
    if event == sg.WIN_CLOSED: break
    if event == '登入':
    	if value['name']=='':
    		my_text.update('   账号不能为空') #修改标题
    	if value['pwd']=='':
    		my_text.update('   密码不能为空') #修改标题

    	#如果都存在进行APP接口登入
    	data ={
		"username":value['name'],
		"password":value['pwd'],
		"group":"pc"
    	}
    	try:
    		print(API_URL + '/site/login.json')
    		mediaGet =requests.post(API_URL + '/site/login.json', json.dumps(data), headers = headers, timeout = 5)
    		# print(mediaGet)
    		mediaGet = mediaGet.json()
    	except Exception as e:
    		#错误提示
    		print(e)
    		sg.popup_error('网络异常, 请稍后重试!',icon=icon_)
    		continue


    	

    	if mediaGet['code']!=200:
    		print(mediaGet['message'])
    		my_text.update(mediaGet['message']) #修改标题
    		continue;

    	if mediaGet['code']==200:
    		sg.SystemTray.notify('登入成功..', '欢迎用户:'+mediaGet['data']['member']['nickname'])
    	# 	# print(1)

    	window.close()
    	#获取目前已经存在的分类
    	values = []
    	cate =requests.get(API_URL + '/live/all-cate.json', headers = headers, timeout = 30)
    	for cate_ in cate.json()['data']['list']:
    		values.append(cate_['name'])

    	#获取直媒体设备
    	pygame.camera.init()
    	shexiangtou=pygame.camera.list_cameras()
    	# print(camera_id_list)
    	

    	#开启新的页面
    	layout = [
    	[sg.Text('直播类型:',pad=((0, 0), (0, 0)),font=('宋体', 12)),sg.Listbox(values=values,key='list',size=(30,7))],
    	[sg.Text('视频设备:',pad=((0, 0), (0, 0)),font=('宋体', 12)),sg.Listbox(values=shexiangtou,key='video',size=(30,2))],
    	[sg.Text('音频设备:',pad=((0, 0), (0, 0)),font=('宋体', 12)),sg.Listbox(values=Audio_List,key='audio',size=(30,2))],
    	[sg.Text('开播标题:',pad=((0, 0), (0, 0)),font=('宋体', 12)),sg.InputText('',key='title',size=(80, 1))],

    	[sg.Button(button_text="开始直播",        # 按钮显示文本
                   tooltip='开始直播',             # 鼠标滑到按钮时显示的文本
                   border_width=0,             # 按钮边框
                   size=(15, 1),              # 按钮的长度,高度
                   auto_size_button=True,      # 自否自适应
                   button_color=('black', 'white'),  # 按钮字体颜色, 按钮的背景色
                   font=('宋体', 12),        # 设置字体,大小
                   bind_return_key=False,    # 是否绑定按键
                   focus=True,              # 鼠标是否放置在此按钮上
                   pad=((85, 0), (20, 0)),    # 设置元素的间距 (左,右),(上,下)
                   # key='START-EXEC',       # 元素唯一标示
                   visible=True
    	)]
    	]

    	liveOpen = sg.Window('开始直播', layout,grab_anywhere=True,size=(300,380),icon=icon_)
    	# sg.SystemTray.notify('登入成功..', '欢迎用户:'+mediaGet['data']['member']['nickname'])
    	event, value = liveOpen.read()
    	while True:
		    event, value = liveOpen.read()
		    if event == sg.WIN_CLOSED: break
		    if event == '开始直播':
		    	#进行开始直播
		    	#检测未选 进行提示
		    	if value['list'] == []:
		    		sg.popup_error('请选择直播类型!',icon=icon_) 
		    		continue;

		    	if value['title'] == '':
		    		sg.popup_error('请输入开播标题!',icon=icon_) 
		    		continue;
		    	# video
		    	if value['video'] == []:
		    		sg.popup_error('请选择设备!',icon=icon_) 
		    		continue;

		    	if value['audio'] == []:
		    		sg.popup_error('请选择设备!',icon=icon_) 
		    		continue;
		    	

		    	vate_id = '';
		    	for cate_ in cate.json()['data']['list']:
		    		if value['list'][0] ==cate_['name']:
		    			vate_id =cate_['id']
		    	#执行查询音频命令
		    	# audio_ok = subprocess.run('',encoding="utf-8" , shell=True)
		    	#检测是否存在 不存在提示
		    	if vate_id!="":
		    		#开始请求直播接口
		    		data={
		    		"cate_id":vate_id,
					"title":value['title']
		    		}
		    		headers['x-api-key'] = mediaGet['data']['access_token'];

		    		live =requests.post(API_URL + '/live/start-live.json', json.dumps(data), headers = headers, timeout = 30)
		    		live =live.json()

		    		if live['code']!=200:
			    		sg.popup_error(live['message']) 
			    		continue;
			    	
			    	#进行推流直播 ffmpeg -f dshow -i video="USB2.0 PC CAMERA" -f dshow -i audio="麦克风 (2- USB2.0 MIC)" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/123

			    	cmd_rtmp = __DIR__+'\\bin\\ffmpeg -f dshow -i video="'+value['video'][0]+'"  -f dshow -i audio="'+value['audio'][0]+'" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv "' + live['data']['detail']['video']+'" -loglevel quiet ';
			    	cmd_lx = subprocess.Popen(cmd_rtmp,encoding="utf-8" , shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
			    	# sg.SystemTray.notify('开播成功', '下播请关闭摄像头窗口..')
			    	# print(live['data']['detail']['video'])
			    	print(cmd_rtmp)
			    	liveOpen.disappear() # 窗口隐藏

			    	sg.popup('开播成功!下播请关闭摄像头窗口然后等待提示! 请点击ok继续',icon=icon_)
			    	time.sleep(10)
			    	# cmd_play = __DIR__+'\\bin\\ffplay -f dshow -i video="'+value['video'][0]+'" -loglevel quiet ';
			    	cmd_play = __DIR__+'\\bin\\ffplay ' + live['data']['detail']['video'];
			    	print(cmd_play)
			    	subprocess.run(cmd_play,encoding="utf-8" , shell=True)
			    	print(cmd_lx.pid)
			    	kill_process(cmd_lx.pid)
			    	cmd_lx.kill()
			    	# subprocess.Popen.kill(proc1)
			    	# cmd_lx.terminate()
			    	# Popen.wait()
			    	#如果退出运行- 直接进行下播
			    	live_id = live['data']['detail']['id']
			    	data = {
			    	"live_id":live_id
			    	}
			    	live =requests.post(API_URL + '/live/live-off.json', json.dumps(data), headers = headers, timeout = 30)
			    	liveOpen.reappear() #展示窗口
			    	sg.popup('下播成功!',icon=icon_)
			    	print(live.json())
			    	# ffplay -f dshow -i video="USB2.0 PC CAMERA"

					#调用ffmpeg进行直播推流data
					# cmd_str =__DIR__+f'\\\bin\\ffmpeg -hide_banner -list_devices  true -f dshow -i 0 -loglevel quiet '
					# cmd =subprocess.run(cmd_str, encoding="utf-8" , shell=True)
					# print(cmd)


	    	#进行直播接口请求

    	# 
    	# print(mediaGet.json())


    	# sg.popup_ok('66')
    	# sg.SystemTray.notify('Notification Title', 'This is the notification` message')
    	#进行检测提示账户密码不能为空

    if event == 'Clean':
        my_text.update('')
# window.close()

打包程序
 pyinstaller  -i "C:/Users/DELL/Desktop/live-exe/bin/icon/favicon.ico" index.py  --distpath "C:/Users/DELL/Desktop/live-exe/" --noconsole --clean
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值