Qt Audio and Video Development 23-Control general de video

I. Introducción

En el sistema de videovigilancia anterior, de acuerdo con las necesidades de los diferentes usuarios, se han fabricado una variedad de kernels de videovigilancia. Hay kernels ffmpeg, kernels vlc, kernels mpv y kernels Haikang sdk, para hacerlos universales La función de diferentes kernels es muy conveniente para cambiar. Por ejemplo, pro cambia directamente el nombre de variable de DEFINE, por lo que es necesario hacer el uso de varios kernels en la misma interfaz, para que se vea muy ordenada, por lo que un propósito general se refina especialmente más adelante. Control de video. Este control no tiene una función de control de reproducción de video específica. Debe implementarse llamando a métodos específicos de acuerdo con diferentes núcleos. Cuando necesite agregar Dahua SDK u otros acuerdos de terceros fabricantes más adelante, puede aplicar directamente este control de video general. En el futuro, agregar un nuevo kernel de monitoreo puede ahorrar mucho trabajo. Básicamente, solo necesita hacer el análisis del kernel, y el resto de las interfaces comunes y las imágenes de dibujo se pasan directamente al control de video común.

Funciones generales de control de video:

  1. Puede establecer el tamaño del borde
  2. El color del borde se puede configurar
  3. Se pueden configurar dos etiquetas OSD
  4. Puede establecer si se dibuja la etiqueta OSD
  5. Puede configurar el texto o la imagen de la etiqueta
  6. Puede configurar la posición de OSD esquina superior izquierda + esquina inferior izquierda + esquina superior derecha + esquina inferior derecha
  7. Se pueden configurar texto de estilo OSD + fecha + hora + fecha y hora + imágenes
  8. Forma flotante translúcida personalizada, una fila de botones
  9. El botón flotante puede ser una configuración personalizada, incluido el color de fondo + el color de la prensa
  10. Señala en qué botón flotante se hizo clic
  11. Capaz de identificar el archivo arrastrado y notificar la URL
  12. Proporcionar interfaces como abrir cerrar pausa

2. Características

  1. Admite cambio de pantalla múltiple, cambio de pantalla completa, etc., incluido el cambio de pantalla 1 + 4 + 6 + 8 + 9 + 13 + 16 + 25 + 36 + 64.
  2. Soporte alt + entrar en pantalla completa, esc salir de pantalla completa.
  3. Cuadro de información personalizado + cuadro de error + cuadro de consulta + cuadro de aviso en la esquina inferior derecha (incluidos varios formatos).
  4. Se pueden cambiar 17 conjuntos de estilos de piel a voluntad, todos los estilos están unificados, incluidos los menús.
  5. Mueva el mouse en el tablero del cardán para resaltar, y las ocho direcciones se identificarán con precisión.
  6. La barra de herramientas de la pantalla inferior (interruptor de división de pantalla + sonido de captura de pantalla y otras configuraciones) se mueve hacia arriba y se resalta.
  7. El logotipo + el nombre del software chino + el nombre del software en inglés se pueden cambiar en el archivo de configuración.
  8. Encapsula el mapa de Baidu, el cambio de vista, la pista de movimiento, la posición del dispositivo y el clic del mouse para obtener la latitud y la longitud, etc.
  9. Admite mapa de imagen, el botón del dispositivo se puede arrastrar libremente en el mapa de imagen para guardar automáticamente la información de ubicación.
  10. En el mapa de Baidu y el mapa de imágenes, haga doble clic en el video para obtener una vista previa del video de la cámara en tiempo real.
  11. Ventana de pila, cada ventana es un qwidget separado, conveniente para escribir su propio código.
  12. El menú de clic derecho del mouse superior puede controlar dinámicamente la visualización y la ocultación del tiempo CPU + panel superior izquierdo + panel inferior izquierdo + panel superior derecho + panel inferior derecho, y admite restaurar el diseño predeterminado.
  13. La barra de herramientas puede colocar varios iconos pequeños y cerrar iconos.
  14. Los lados izquierdo y derecho se pueden arrastrar y estirar, y las posiciones de ancho y alto se memorizan automáticamente y se restaurarán después de reiniciar.
  15. Haga doble clic en el nodo de la cámara para reproducir automáticamente el video, haga doble clic en el nodo para agregar automáticamente videos en secuencia y saltará automáticamente al siguiente. Haga doble clic en el nodo principal para agregar automáticamente todos los videos debajo del nodo.
  16. El nodo de la cámara se arrastra a la ventana correspondiente para reproducir el video y los archivos locales son compatibles con la reproducción directa.
  17. El cuadro de video admite arrastrar e intercambiar, y responde instantáneamente.
  18. Haga doble clic en el nodo + arrastre el nodo + arrastre el formulario para intercambiar posiciones, y url.txt se actualizará automáticamente.
  19. Admite la reproducción de video del canal de carga desde url.txt, recuerda automáticamente el video correspondiente al último canal y se abre y reproduce automáticamente después de que se inicia el software.
  20. El control de la barra de volumen en la esquina inferior derecha se oculta automáticamente cuando se pierde el enfoque, y la barra de volumen tiene un icono de silencio.
  21. Mapa en línea integrado de Baidu y mapa fuera de línea, puede agregar la ubicación correspondiente del dispositivo, generar automáticamente un mapa, admitir el zoom y agregar superposiciones, etc.
  22. Arrastre el video fuera de la ventana del canal para eliminarlo automáticamente.
  23. El botón derecho del mouse puede eliminar el actual + todos los videos, la captura de pantalla actual + todos los videos.
  24. Administración de grabadoras, administración de cámaras, puede agregar, eliminar, modificar, importar y exportar información de impresión y aplicar inmediatamente la información del nuevo dispositivo para generar una lista de árbol sin reiniciar.
  25. Puede habilitar libremente si desea cargar el mapa en el archivo profesional.
  26. Se pueden cambiar libremente dos tipos de núcleos para la reproducción de video, vlc + ffmpeg, ambos se pueden configurar en pro.
  27. Se puede configurar el sondeo de pantalla 1 + 4 + 9 + 16, el intervalo de sondeo y el tipo de flujo de sondeo se pueden configurar, simplemente haga clic en el botón Iniciar sondeo en el lado derecho de la barra de herramientas en la parte inferior de la interfaz principal y haga clic nuevamente para detener el sondeo .
  28. De forma predeterminada, el puntero del mouse se ocultará automáticamente sin operación durante más de 10 segundos.
  29. Admite equipos de búsqueda onvif, admite cualquier cámara onvif, incluidos, entre otros, Haikang Dahuayu Shitiandi Weiye Huawei, etc.
  30. Admite el control onvif PTZ, puede mover la cámara PTZ hacia arriba, abajo, izquierda y derecha, incluido el restablecimiento y el ajuste de enfoque.
  31. Al mismo tiempo, admite bases de datos como sqlite, mysql y postsql.
  32. El video se puede guardar, el almacenamiento de tiempo o el almacenamiento de un solo archivo es opcional y el intervalo de almacenamiento es opcional.
  33. Puede configurar el método de comunicación de transmisión de video tcp + udp, y puede configurar la decodificación de video como prioridad de velocidad, prioridad de calidad, ecualización, etc.
  34. Puede configurar el tipo de decodificación rígida, admite qsv, dxva2, d3d11va, etc.
  35. De forma predeterminada, opengl se usa para dibujar video, que tiene un consumo de recursos de CPU ultra bajo y admite el dibujo en formato yuyv y nv12, lo cual es muy impresionante.
  36. Altamente personalizable, los usuarios pueden derivar fácilmente sus propias funciones sobre esta base, admitiendo sistemas Linux y Mac.

Tres, representaciones

Inserte la descripción de la imagen aquí

Cuatro sitios relacionados

  1. Sitio nacional: https://gitee.com/feiyangqingyun/QWidgetDemo
  2. Sitio internacional: https://github.com/feiyangqingyun/QWidgetDemo
  3. Página de inicio personal: https://blog.csdn.net/feiyangqingyun
  4. Página de inicio de Zhihu: https://www.zhihu.com/people/feiyangqingyun/
  5. Dirección de experiencia: https://blog.csdn.net/feiyangqingyun/article/details/97565652

Cinco, el código central

void VideoWidget::paintEvent(QPaintEvent *)
{
    //如果不需要绘制
    if (!drawImage) {
        return;
    }

    //qDebug() << TIMEMS << "paintEvent" << objectName();
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing);

    //绘制边框
    drawBorder(&painter);
    if (!image.isNull()) {
        //绘制背景图片
        drawImg(&painter, image);
        //绘制标签
        drawOSD(&painter, osd1Visible, osd1FontSize, osd1Text, osd1Color, osd1Image, osd1Format, osd1Position);
        drawOSD(&painter, osd2Visible, osd2FontSize, osd2Text, osd2Color, osd2Image, osd2Format, osd2Position);
    } else {
        //绘制背景
        drawBg(&painter);
    }
}

void VideoWidget::drawBorder(QPainter *painter)
{
    if (borderWidth == 0) {
        return;
    }

    painter->save();
    QPen pen;
    pen.setWidth(borderWidth);
    pen.setColor(hasFocus() ? focusColor : borderColor);
    painter->setPen(pen);
    painter->drawRect(rect());
    painter->restore();
}

void VideoWidget::drawBg(QPainter *painter)
{
    painter->save();

    //背景图片为空则绘制文字,否则绘制背景图片
    if (bgImage.isNull()) {
        painter->setFont(this->font());
        painter->setPen(palette().foreground().color());
        painter->drawText(rect(), Qt::AlignCenter, bgText);
    } else {
        //居中绘制
        int pixX = rect().center().x() - bgImage.width() / 2;
        int pixY = rect().center().y() - bgImage.height() / 2;
        QPoint point(pixX, pixY);
        painter->drawImage(point, bgImage);
    }

    painter->restore();
}

void VideoWidget::drawImg(QPainter *painter, QImage img)
{
    painter->save();

    int offset = borderWidth * 1 + 0;
    if (fillImage) {
        QRect rect(offset / 2, offset / 2, width() - offset, height() - offset);
        painter->drawImage(rect, img);
    } else {
        //按照比例自动居中绘制
        img = img.scaled(width() - offset, height() - offset, Qt::KeepAspectRatio);
        int pixX = rect().center().x() - img.width() / 2;
        int pixY = rect().center().y() - img.height() / 2;
        QPoint point(pixX, pixY);
        painter->drawImage(point, img);
    }

    painter->restore();
}

void VideoWidget::drawOSD(QPainter *painter,
                          bool osdVisible,
                          int osdFontSize,
                          const QString &osdText,
                          const QColor &osdColor,
                          const QImage &osdImage,
                          const VideoWidget::OSDFormat &osdFormat,
                          const VideoWidget::OSDPosition &osdPosition)
{
    if (!osdVisible) {
        return;
    }

    painter->save();

    //标签位置尽量偏移多一点避免遮挡
    QRect osdRect(rect().x() + (borderWidth * 2), rect().y() + (borderWidth * 2), width() - (borderWidth * 5), height() - (borderWidth * 5));
    int flag = Qt::AlignLeft | Qt::AlignTop;
    QPoint point = QPoint(osdRect.x(), osdRect.y());

    if (osdPosition == OSDPosition_Left_Top) {
        flag = Qt::AlignLeft | Qt::AlignTop;
        point = QPoint(osdRect.x(), osdRect.y());
    } else if (osdPosition == OSDPosition_Left_Bottom) {
        flag = Qt::AlignLeft | Qt::AlignBottom;
        point = QPoint(osdRect.x(), osdRect.height() - osdImage.height());
    } else if (osdPosition == OSDPosition_Right_Top) {
        flag = Qt::AlignRight | Qt::AlignTop;
        point = QPoint(osdRect.width() - osdImage.width(), osdRect.y());
    } else if (osdPosition == OSDPosition_Right_Bottom) {
        flag = Qt::AlignRight | Qt::AlignBottom;
        point = QPoint(osdRect.width() - osdImage.width(), osdRect.height() - osdImage.height());
    }

    if (osdFormat == OSDFormat_Image) {
        painter->drawImage(point, osdImage);
    } else {
        QDateTime now = QDateTime::currentDateTime();
        QString text = osdText;
        if (osdFormat == OSDFormat_Date) {
            text = now.toString("yyyy-MM-dd");
        } else if (osdFormat == OSDFormat_Time) {
            text = now.toString("HH:mm:ss");
        } else if (osdFormat == OSDFormat_DateTime) {
            text = now.toString("yyyy-MM-dd HH:mm:ss");
        }

        //设置颜色及字号
        QFont font;
        font.setPixelSize(osdFontSize);
        painter->setPen(osdColor);
        painter->setFont(font);

        painter->drawText(osdRect, flag, text);
    }

    painter->restore();
}

Supongo que te gusta

Origin blog.csdn.net/feiyangqingyun/article/details/108355000
Recomendado
Clasificación