提问人:LeXela-ED 提问时间:6/3/2023 最后编辑:נירLeXela-ED 更新时间:6/5/2023 访问量:162
QML多媒体无法播放用ffmpeg生成的m3u8
QML multimedia cannot play m3u8 that is generated with ffmpeg
问:
使用以下命令,我尝试通过网络流式传输 IP 摄像机:
ffmpeg -re -i "rtsp://<user>:<password>@<ip>:<port>" -c:v copy -c:a copy -hls_segment_type mpegts -hls_list_size 5 -hls_wrap 5 -hls_time 2 -hls_flags split_by_time -segment_time_delta 1.00 -reset_timestamps 1 -hls_allow_cache 0 -movflags faststart live.m3u8```
此命令生成 live.m3u8 和五个 ts 文件:live0.ts、live1.ts、live2.ts、live3.ts 和 live4。转换进行得很顺利。在某个随机点,live.m3u8 的内容如下:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE:92
#EXTINF:2.000000,
live2.ts
#EXTINF:2.000000,
live3.ts
#EXTINF:2.035800,
live4.ts
#EXTINF:2.000000,
live0.ts
#EXTINF:1.963278,
live1.ts
但是,当我尝试使用以下QML代码播放live.m3u8时,它只播放了其中的第一段:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtMultimedia 5.15
Window
{
width: 640
height: 480
visible: true
Item
{
anchors.fill: parent
MediaPlayer
{
id: mediaplayer
source: "path-to-live/live.m3u8"
videoOutput: videoOutput
}
VideoOutput
{
id: videoOutput
anchors.fill: parent
}
MouseArea
{
anchors.fill: parent
onPressed: mediaplayer.play();
}
}
}
有趣的是:我手动删除了 live.m3u8,显然,ffmpeg 之后又生成了一个!然后我点击了QML程序窗口,令人惊讶的是,它像第一次运行时预期的那样不间断地播放流!
这里有什么问题?我错过了什么?我应该更改 ffmpeg 命令还是对我的 qml 代码做点什么?有任何想法或帮助吗?
先谢谢你。
答:
我根本无法开始工作,但是,我怀疑您的问题是在加载时被读取,而不是在按下时被读取。这意味着,如果您在程序运行时重新生成,则其中的信息可能会过时,它不会接受更改。为了获得最新的更改,您应该考虑尽可能晚地分配,例如在点击时。live.m3u8
m3u8
MouseArea
m3u8
live.m3u8
live.m3u8
mediaplayer.source
MouseArea
MouseArea
{
anchors.fill: parent
onPressed: {
mediaplayer.source = "";
mediaplayer.source = "file-url-to-live/live.m3u8";
mediaplayer.play();
}
}
另外,既然你有,你可以转码到任何你想要的东西,那么,你为什么不把它转码到你知道Qt可以播放的单个文件呢?对我来说,以下内容适用于我的 Windows 机器(即我正在强制使用音频编解码器、视频编解码器和文件格式容器)。ffmpeg
mp3
mpeg4
avi
ffmpeg -y -i ... -c:v mpeg4 -c:a lipbmp3lame live.avi
另一种选择是使用 mpeg(例如 文件格式容器中以 25 fps 的速度播放的音频)。如果您无法使用,这将是一个更好的选择:mp3
mpeg1 video
mpg
avi
ffmpeg -y -i ... -c:v mpeg1video -c:a lipbmp3lame -r 25 live.mpg
即使你有 Qt5.15.x 导入,看起来你使用的是 Qt6 风格的多媒体。
在 Qt5.15.x 中,记录的用法是指 ,而不是相反。UI/UX 位于您可以放置在任何地方并作为顶级组件。将它放在 .事实上,在您的示例中实际上不需要该组件,因此,我对其进行了重构:VideoOutput
VideoOutput
MediaPlayer
VideoOutput
MediaPlayer
Item
Item
// Qt5.15.x version
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtMultimedia 5.15
Window
{
width: 640
height: 480
visible: true
MediaPlayer
{
id: mediaplayer
}
VideoOutput
{
id: videoOutput
source: mediaplayer
anchors.fill: parent
MouseArea {
anchors.fill: parent
onPressed: {
mediaplayer.source = "";
mediaplayer.source = "file:///C:/Temp/Vid/live.avi";
mediaplayer.play();
}
}
}
}
在Qt6中,不需要为导入提供版本号,因此原始代码仍然存在。但是,我关于没有必要的评论也成立:Item
// Qt6 version
import QtQuick
import QtQuick.Window
import QtQuick.Controls
import QtQuick.Layouts
import QtMultimedia
Window {
MediaPlayer {
id: mediaPlayer
videoOutput: videoOutput
}
VideoOutput {
id: videoOutput
anchors.fill: parent
MouseArea {
anchors.fill: parent
onPressed: {
mediaplayer.source = "";
mediaplayer.source = "file:///C:/Temp/Vid/live.avi";
mediaplayer.play();
}
}
}
}
引用:
- https://doc.qt.io/qt-5/qml-qtmultimedia-videooutput.html
- https://doc.qt.io/qt-6/qml-qtmultimedia-videooutput.html
评论
ffplay
VLC
评论