Qt audio and video development 12-mpv decoding and playback

I. Introduction

I played vlc decoding and ffmpeg decoding before. Some time ago, a customer needed to switch to mpv decoding, so he studied how to use mpv. After using mpv, I found that I couldn’t put it down. This thing is naturally suitable for geeks and programmers. Various processes are encapsulated into commands and attribute calls, such as playback progress, you only need to read the attribute time-pos, if you want to read the volume, you only need to read the attribute volume, and set the volume directly to set the attribute volume corresponding to It’s worth it, my dear, this is awesome, isn’t this the way we dream of handling it? You only need to encapsulate a few general processing interfaces (read property mpv_get_property, set property mpv_set_property, execute command mpv_command_node, set parameter mpv_set_option), which covers most of the functions. You say it is simple and easy to use, but this is what you want The effect is! ! !

mpv is a multi-platform open source player based on MPlayer and MPlayer2. It is an open source, cross-platform video player with a minimalist GUI interface and rich command line control. It has a wide range of output device support on Linux, built-in ffmpeg decoder, supports most video and audio formats, supports local playback and network playback, supports ass special effects subtitles, and has excellent GPU decoding capabilities. MPV has all the functions that a standard player should have. You can play all kinds of videos and control the playback through common shortcut keys. It is often hailed as a god-level player on the Internet, a god-like existence!

To display the video through mpv, only the handle is found at present. The callback is not found. I don’t know if it is not supported. I searched the manual and instructions on the official website, but I didn’t find it. There is another problem with setting the playback handle through mpv_set_option. , I don’t know how to pass in parameters on linux, if anyone has a way to leave a message, thank you.

Decoding playback process:

  1. Call mpv_create to create an instance.
  2. Call mpv_set_option to set the playback handle.
  3. Call mpv_set_property to set some properties, such as enabling keyboard input.
  4. Call mpv_set_option to set some parameters such as hard decoding, timeout, etc.
  5. Call mpv_initialize to initialize the instance.
  6. Call mpv_command_async to execute the command loadfile to open the file for playback.
  7. Call mpv_terminate_destroy to release the instance.

2. Features

  1. Multi-threaded real-time playing video stream + local video, etc.
  2. Support windows+linux+mac.
  3. Multi-threaded display images, not stuck in the main interface.
  4. Reconnect the webcam automatically.
  5. Can set whether to save to file and file name.
  6. You can drag files directly to the mpvwidget control to play.
  7. Support common video streams such as h265 video stream + rtmp.
  8. Can pause and resume playing.
  9. Support storage of single video files and timing storage of video files.
  10. Customize the top floating bar, send a click signal notification, and set whether to enable it.
  11. You can set the screen stretch fill or equal proportion fill.
  12. Can take screenshots (original pictures) and screenshots of videos.
  13. The video file stores MP4 files.
  14. Supports hard decoding such as qsv, dxva2, d3d11va, etc.

Three, renderings

Insert picture description here

Four, related sites

  1. Domestic site: https://gitee.com/feiyangqingyun/QWidgetDemo
  2. International site: https://github.com/feiyangqingyun/QWidgetDemo
  3. Personal homepage: https://blog.csdn.net/feiyangqingyun
  4. Zhihu Homepage: https://www.zhihu.com/people/feiyangqingyun/
  5. Experience address: https://blog.csdn.net/feiyangqingyun/article/details/97565652

Five, the core code

bool MpvThread::init()
{
    //判断该摄像机是否能联通
    if (checkConn && isRtsp) {
        if (!checkUrl(url, checkTime)) {
            return false;
        }
    }

    //创建实例
    mpvPlayer = mpv_create();

    //回调方式和句柄方式两种分别处理
    if (callback) {
        return false;
    } else {
        //设置播放句柄
        if (playWidget == NULL) {
            return false;
        }

        //下面是WIN上的方法,如何在linux上的方法还没找到
        HWND wid = (HWND)playWidget->winId();
        mpv_set_option(mpvPlayer, "wid", MPV_FORMAT_INT64, &wid);
    }

    //请求级别日志消息
    mpv_request_log_messages(mpvPlayer, "info");
    //启用默认绑定
    setValue("input-default-bindings", "yes");
    //启用键盘输入
    setValue("input-vo-keyboard", "yes");

    //设置硬件加速 none auto any d3d11va dxva2
    setOption("hwdec", hardware);
    //设置通信协议 tcp udp
    setOption("rtsp-transport", transport);
    //设置网络超时时间 单位秒
    setOption("network-timeout", 3);

    //初始化实例
    if (mpv_initialize(mpvPlayer) < 0) {
        return false;
    }

    //设置保存文件,目前发现有部分视频流不行,原因未知
    this->initSave();

    //创建事件管理器
    if (callbackevent) {
        attachEvents(mpvPlayer);
        mpv_set_wakeup_callback(mpvPlayer, wakeup, this);
    }

    QByteArray data = url.toUtf8();
    //command(QVariantList() << "loadfile" << data.data());
    const char *args[] = {"loadfile", data.data(), NULL};
    if (mpv_command_async(mpvPlayer, 0, args) < 0) {
        return false;
    }

    //打印支持的属性列表和命令列表
    //qDebug() << TIMEMS << getValue("property-list") << getValue("command-list");
    //打印组件的版本
    //qDebug() << TIMEMS << getValue("mpv-version") << getValue("ffmpeg-version");
    //qDebug() << TIMEMS << "init mpv finsh";
    return true;
}

void MpvThread::free()
{
    if (mpvPlayer != NULL) {
        mpv_terminate_destroy(mpvPlayer);
        mpvPlayer = NULL;
    }

    //qDebug() << TIMEMS << "close mpv ok";
}

Guess you like

Origin blog.csdn.net/feiyangqingyun/article/details/108069600