最近突然想做一个视频播放器,可以在线看视频,关键还没用广告,不用会员,下面给大家介绍一下怎么制作
工具:
Python
Qt
phantomjs
先给大家展示一下效果
下面上代码
导入库:
from PyQt5.QtWidgets import *
from PyQt5 import QtWidgets, QtNetwork, QtCore
from main_windows import Ui_MainWindow
from PyQt5.QtCore import pyqtSignal, QThread, QUrl
import sys
import time
from bs4 import BeautifulSoup
from Config import *
import urllib
from selenium import webdriver
import webbrowser
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings
这里是selenium进行爬虫,因为相对于request,他更不容易被检测到,不用考虑那么多反爬机制,在就是,在爬取时需要进行一次点击(这是主要原因),浏览器使用的 phantomjs,phantojms相对较小且不用下载驱动,可直接使用
爬虫相关部分代码,这里爬取的某某艺的搜索引擎:
class aiqiyi(QThread):
''' 爱奇艺网站搜索 '''
trigger = pyqtSignal(str)
def __init__(self,keywords=True):#do_create_data放在最后
super(aiqiyi, self).__init__()
self.keywords = keywords
def run(self):
''' :return: '''
keywords = urllib.parse.quote(self.keywords)
url = aiqiyi_url.format(keywords=keywords)
driver = webdriver.PhantomJS()
driver.get(url)
aElements = driver.find_elements_by_tag_name("a")
#这里通过循环a标签获取“...”并点击他,如果不执行这一步则无法获取到全部的剧集链接
for name in aElements:
if str(name.get_attribute("href")) == "javascript:void(0);"and name.text == '...':
name.click()
soup = BeautifulSoup(driver.page_source, 'lxml')
driver.quit()
list = soup.find("div", {"desc": "搜索列表"})
for i in list:
try:
a =i.find('span', {'class': 'item-type'})
type =a.text
# print(type)
Name = i.find('a', {'target': '_blank'})['title']
# print(Name)
self.trigger.emit(type + "----"+Name)
if type == '电视剧' or type == '动漫':
all = i.find('ul',{"class":"album-list",'style':""})
for t in all :
# print(t)
item = t.find('a',{"class":"album-link"})
# print(item)
ji_url = item['href']
if str(ji_url).split(":")[-1] == str(ji_url).split(":")[0]:
ji_url = "http:"+ji_url
ji_name = item.text
self.trigger.emit("第{}集:{}".format(ji_name,ji_url))
elif type == '电影':
link = i.find('a',{'class':'qy-search-result-btn'})
self.trigger.emit("链接:http:{}".format(link['href']))
pass
except:
pass
self.trigger.emit('搜索完成')
在制作主界面时,遇到了一些问题以及做了一些优化,在这里也给大家分享一下
一就是QtWebEngineWidgets无法播放视频文件,在大佬们的博客中我找到的解决办法,在这里也感谢ZeronoFreya的分享,解决办法如下:
加载flash的动态链接库并对QtWebEngineWidgets进行重编译添加mp4解码器,重编译方法在这就不说,外面有很多大佬的博客都有详细介绍
argvs = sys.argv
# 支援flash
argvs.append('--ppapi-flash-path=./pepflashplayer.dll')
二就是QtWebEngineWidgets窗口不能全屏,这里我只将MP3、MP4进行了全屏设置,flash不能全屏,有大佬知道方法的可以分享一下,解决方法如下:
@QtCore.pyqtSlot("QWebEngineFullScreenRequest")
def _fullScreenRequested(self, request):
request.accept()
if request.toggleOn():
self.webview.setParent(None)
self.webview.showFullScreen()
else:
self.webview.setParent(self)
self.webview.setGeometry(0, 0, self.width() - 300, self.height())
self.webview.showNormal()
还做了一个小优化就是重载resizeEvent函数让窗口可以等比例放大缩小,相关代码:
def resizeEvent(self, event):
self.webview.setGeometry(0,0,self.width()-300,self.height())
self.result.setGeometry(self.width()-300,100,300,self.height()-168)
self.label.setGeometry(self.width()-280, 10, 61, 31)
self.label_2.setGeometry(self.width()-280, 50, 41, 31)
self.label_3.setGeometry(self.width()-300, self.height()-75, 171, 41)
self.sosuokuang.setGeometry(self.width()-200, 10, 171, 31)
self.comboBox.setGeometry(self.width()-200, 50, 91, 31)
self.start.setGeometry(self.width()-100, 50, 75, 31)
这几个主要地方讲完后面就没什么了,直接上所有代码:
class MainForm(QMainWindow, Ui_MainWindow):
def __init__(self):
super(MainForm, self).__init__()
self.setupUi(self)
self.start.clicked.connect(self.Start_Game)
self.thread = None
# 双击开始播放
self.result.doubleClicked.connect(lambda: self.play())
self.thread_1 = None
# QT浏览器
self.webview = QWebEngineView(self)
self.webview.settings().setAttribute(QWebEngineSettings.PluginsEnabled, True)
self.webview.settings().setAttribute(QWebEngineSettings.JavascriptEnabled, True)
self.webview.settings().setAttribute(QWebEngineSettings.FullScreenSupportEnabled, True))
self.webview.page().fullScreenRequested.connect(self._fullScreenRequested)
QtNetwork.QNetworkProxyFactory.setUseSystemConfiguration(False)
@QtCore.pyqtSlot("QWebEngineFullScreenRequest")
def _fullScreenRequested(self, request):
request.accept()
if request.toggleOn():
self.webview.setParent(None)
self.webview.showFullScreen()
else:
self.webview.setParent(self)
self.webview.setGeometry(0, 0, self.width() - 300, self.height())
self.webview.showNormal()
def resizeEvent(self, event):
# pass
self.webview.setGeometry(0,0,self.width()-300,self.height())
self.result.setGeometry(self.width()-300,100,300,self.height()-168)
self.label.setGeometry(self.width()-280, 10, 61, 31)
self.label_2.setGeometry(self.width()-280, 50, 41, 31)
self.label_3.setGeometry(self.width()-300, self.height()-75, 171, 41)
self.sosuokuang.setGeometry(self.width()-200, 10, 171, 31)
self.comboBox.setGeometry(self.width()-200, 50, 91, 31)
self.start.setGeometry(self.width()-100, 50, 75, 31)
def play(self):
global PLAY_WAY
line = self.result.currentRow()
Text = self.result.item(line).text()
url = str(Text).split(":")[-1]
if self.comboBox.currentText() == '线路一':
url = vip1_url.format(video_url=url)
elif self.comboBox.currentText() == '线路二':
url = vip2_url.format(video_url=url)
self.webview.load(QUrl(str(url)))
def outPrint(self,text):
if text == '搜索完成':
self.label_3.setText("<html><head/><body><p><span style=\" font-size:10pt; font-weight:600; color:#ff0000;\">搜索完成!</span></p></body></html>")
return
Time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
if text.split("----")[-1] != text.split("----")[0]:
self.result.addItem(str(text))
else:
self.result.addItem(" " + str(text))
def Start_Game(self):
''' 开始搜索 :return: '''
Name = self.sosuokuang.text()
self.label_3.setText(
"<html><head/><body><p><span style=\" font-size:10pt; font-weight:600; color:#ff0000;\">搜索中~</span></p></body></html>")
self.thread = aiqiyi(Name)
self.thread.start()
self.thread.trigger.connect(self.outPrint)
就此一个简单的在线视频播放器制作完成,妈妈再也不用担心我看视频没用会员啦~