PyQt5:QMediaplayer,QVideowidget播放视频(4)

2023-03-10 13:08:14 浏览数 (2)

PyQt5:QMediaplayer,QVideowidget播放视频(4)

更新原因

说一下这次更新原因,本来说是不在更新这个系列,但是其他博友实际使用中发现的问题。在linux-ubuntu20.04/raspi-4b 在播放视频的过程中出现了url不识别倒是网络视频无法播放的问题以及本地播放没有音频等相关问题。博主在几周前已经解决,但是最近一直很忙,今天抽空也写了一下相关的linux下播放的相关依赖文件还有代码修改原因。

第三方依赖库

因为在linux的播放依赖的是 gstreamer播放。所以需要下载相关的gstreamer库,本地音频没有声音就是这个原因导致的。

经整理第三方依赖库,如下:

代码语言:javascript复制
gstreamer1.0-qt5 # GStreamer plugin for Qt5
gstreamer1.0-plugins-bad
gstreamer1.0-plugins-ugly
#libgstreamermm-1.0-dev #
gstreamer1.0-plugins-base
gstreamer1.0-plugins-good
gstreamer1.0-tools
gstreamer1.0-pulseaudio
gstreamer1.0-libav

代码修改

如下:

代码修改

代码语言:javascript复制
#增加了平台导入模块
import platform

#修改了url获取方法
	def addFile(self,filePath,fileName):
		url = QUrl()
		media_file = path(filePath)
		if platform.system() == 'Linux' and os.path.isfile(filePath) == False:
			url.setUrl(filePath, QUrl.StrictMode)
		else:
			url = QUrl.fromLocalFile(filePath)
		self.playList.addMedia(QMediaContent(url))
		self.createItem(fileName)
  • 错误提示
代码语言:javascript复制
GStreamer; Unable to play - "file:https://vd1.bdstatic.com/mda-hg6uempmez9u6mqi/sc/mda-hg6uempmez9u6mqi.mp4?auth_key=1562172911-0-0-4c22196ad1d0fcc49402d91336c999c5&bcevod_channel=searchbox_feed&pd=bjh&abtest=all"
Error: "Could not open resource for reading."

在开始时并没有发现什么,在网上也没有查到什么有用信息。在单独使用gstreamer播放,也可以播放,

播放命令如下:

代码语言:javascript复制
gst-play-1.0 --no-interactive https://vd1.bdstatic.com/mda-hg6uempmez9u6mqi/sc/mda-hg6uempmez9u6mqi.mp4?auth_key=1562172911-0-0-4c22196ad1d0fcc49402d91336c999c5&bcevod_channel=searchbox_feed&pd=bjh&abtest=all

后来在又仔细查看了一下错误:

发下url已经被修改了。

代码语言:javascript复制
#原始url
https://vd1.bdstatic.com/mda-hg6uempmez9u6mqi/sc/mda-hg6uempmez9u6mqi.mp4?auth_key=1562172911-0-0-4c22196ad1d0fcc49402d91336c999c5&bcevod_channel=searchbox_feed&pd=bjh&abtest=all
#错误提示url
https://vd1.bdstatic.com/mda-hg6uempmez9u6mqi/sc/mda-hg6uempmez9u6mqi.mp4?auth_key=1562172911-0-0-4c22196ad1d0fcc49402d91336c999c5&bcevod_channel=searchbox_feed&pd=bjh&abtest=all

经过对比会发现:

? 被替换为了 %3

错误定了,就知道原因在哪了。url 被编码导致无法识别。

  • 原理

在实际使用中,url 都会被编码,但是在当前环境中,url只是作为值被传递进去不允许修改。因为gstreamer,url 参数是作为gstramer的原生参数,是编码前的参数,所以要保证不会被编码。

查看qt-url帮助文档如下:QUrl

针对编码的说明如下:

enum QUrl::ParsingMode The parsing mode controls the way QUrl parses strings. ConstantValueDescriptionQUrl::TolerantMode0QUrl will try to correct some common errors in URLs. This mode is useful for parsing URLs coming from sources not known to be strictly standards-conforming.QUrl::StrictMode1Only valid URLs are accepted. This mode is useful for general URL validation.QUrl::DecodedMode2QUrl will interpret the URL component in the fully-decoded form, where percent characters stand for themselves, not as the beginning of a percent-encoded sequence. This mode is only valid for the setters setting components of a URL; it is not permitted in the QUrl constructor, in fromEncoded() or in setUrl(). For more information on this mode, see the documentation for QUrl::FullyDecoded. In TolerantMode, the parser has the following behaviour:

  • Spaces and “ ”: unencoded space characters will be accepted and will be treated as equivalent to “ ”.
  • Single “%” characters: Any occurrences of a percent character “%” not followed by exactly two hexadecimal characters (e.g., “13% coverage.html”) will be replaced by “%”. Note that one lone “%” character will trigger the correction mode for all percent characters.
  • Reserved and unreserved characters: An encoded URL should only contain a few characters as literals; all other characters should be percent-encoded. In TolerantMode, these characters will be accepted if they are found in the URL: space / double-quote / “<” / “>” / “” / “^” / “`” / “{” / “|” / “}” Those same characters can be decoded again by passing QUrl::DecodeReserved to toString() or toEncoded(). In the getters of individual components, those characters are often returned in decoded form.

When in StrictMode, if a parsing error is found, isValid() will return false and errorString() will return a message describing the error. If more than one error is detected, it is undefined which error gets reported. Note that TolerantMode is not usually enough for parsing user input, which often contains more errors and expectations than the parser can deal with. When dealing with data coming directly from the user – as opposed to data coming from data-transfer sources, such as other programs – it is recommended to use fromUserInput(). See also fromUserInput(), setUrl(), toString(), toEncoded(), and QUrl::FormattingOptions.

通过 void QUrl::setUrl(const [QString](https://doc.qt.io/qt-5/qstring.html) &*url*, [QUrl::ParsingMode](https://doc.qt.io/qt-5/qurl.html#ParsingMode-enum) *parsingMode* = TolerantMode)得知默认在实例化方法后,默认构造的编码模式为 TolerantMode

通过上述知道,

默认的 QUrl::TolerantMode编码模式,不支持解析用户的输入使用,会对一些编码进行先关的转换。但是 QUrl::StrictMode接受有效的url输入,对于一般的url都使用。在这里所以选用 QUrl::StrictMode模式。另外还提供了一种方法 : QUrl::fromUserInput(const QString &*userInput*)

QUrl QUrl::fromUserInput(const QString &userInput) Returns a valid URL from a user supplied userInput string if one can be deducted. In the case that is not possible, an invalid QUrl() is returned. Most applications that can browse the web, allow the user to input a URL in the form of a plain string. This string can be manually typed into a location bar, obtained from the clipboard, or passed in via command line arguments. When the string is not already a valid URL, a best guess is performed, making various web related assumptions. In the case the string corresponds to a valid file path on the system, a file:// URL is constructed, using QUrl::fromLocalFile(). If that is not the case, an attempt is made to turn the string into a http:// or ftp:// URL. The latter in the case the string starts with ‘ftp’. The result is then passed through QUrl’s tolerant parser, and in the case or success, a valid QUrl is returned, or else a QUrl(). Examples:

  • qt-project.org becomes http://qt-project.org
  • ftp.qt-project.org becomes ftp://ftp.qt-project.org
  • hostname becomes http://hostname
  • /home/user/test.html becomes file:///home/user/test.html

This function was introduced in Qt 4.6.

博主并没有进行相关的探讨。如果各位看官有关研究,可有评论区说一下。

其他

源码地址:github

其他相关博文:PyQt5:QMediaplayer,QVideowidget播放视频(3)

0 人点赞