video: отправка видео-сообщений (FFmpeg пробинг+транскод H.264/AAC MP4)
- src/video/: video_probe/video_get_info/video_transcode_start (FFmpeg, HAVE_FFMPEG) - chat_core/chat_msg: media_video флаг, chat_core_submit_media_message, транскод перед index - headless: команда attach с --video - chatgui: диалог 'Как видео' + прогресс транскода + sendVideoAttachment - FFmpeg в сборке (configure.ac, Makefile.am, chatgui CMake, build_nix.sh) - debug: категория DEBUG_CATEGORY_VIDEO
This commit is contained in:
1 parent
c8bd5975ae
commit
1855c61275
19 files changed
+1026
-29
No files matched your search
@@ -10,6 +10,7 @@
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QKeyEvent>
|
||||
#include <QFontMetrics>
|
||||
#include <QScrollBar>
|
||||
@@ -19,8 +20,14 @@
|
||||
#include <QDir>
|
||||
#include <QProgressBar>
|
||||
#include <QIcon>
|
||||
#include <QTimer>
|
||||
#include <QFileInfo>
|
||||
#include <cmath>
|
||||
|
||||
extern "C" {
|
||||
#include "video/video.h"
|
||||
}
|
||||
|
||||
static QPushButton *makeIconBtn(const QIcon& icon, const QString &tooltip, QWidget *parent) {
|
||||
auto *btn = new QPushButton(parent);
|
||||
btn->setIcon(icon);
|
||||
@@ -85,6 +92,10 @@ InputBar::InputBar(EmojiPanel *emojiPanel, AudioRecorder *recorder, QWidget *par
|
||||
m_attachPreview->hide();
|
||||
mainLayout->addWidget(m_attachPreview);
|
||||
|
||||
m_videoProgressTimer = new QTimer(this);
|
||||
m_videoProgressTimer->setInterval(150);
|
||||
connect(m_videoProgressTimer, &QTimer::timeout, this, &InputBar::onVideoProgressTick);
|
||||
|
||||
auto *layout = new QHBoxLayout();
|
||||
layout->setSpacing(4);
|
||||
|
||||
@@ -225,13 +236,22 @@ void InputBar::onSendClicked() {
|
||||
if (!hasAttach && text.isEmpty()) return;
|
||||
|
||||
if (hasAttach) {
|
||||
GUI_INFO("send: file=%s name=%s", qPrintable(m_pendingAttachSrc), qPrintable(m_pendingAttachName));
|
||||
emit sendFileAttachment(m_pendingAttachSrc, m_pendingAttachDest, m_pendingAttachName);
|
||||
if (m_pendingAttachAsVideo) {
|
||||
GUI_INFO("send: video=%s name=%s", qPrintable(m_pendingAttachSrc), qPrintable(m_pendingAttachName));
|
||||
emit sendVideoAttachment(m_pendingAttachSrc, m_pendingAttachDest, m_pendingAttachName);
|
||||
m_attachPreviewLabel->setText(QString::fromUtf8("\xF0\x9F\x8E\xAC Перекодирование… 0%"));
|
||||
m_attachPreview->show();
|
||||
m_videoProgressTimer->start();
|
||||
} else {
|
||||
GUI_INFO("send: file=%s name=%s", qPrintable(m_pendingAttachSrc), qPrintable(m_pendingAttachName));
|
||||
emit sendFileAttachment(m_pendingAttachSrc, m_pendingAttachDest, m_pendingAttachName);
|
||||
m_attachPreview->hide();
|
||||
}
|
||||
m_pendingAttachSrc.clear();
|
||||
m_pendingAttachDest.clear();
|
||||
m_pendingAttachName.clear();
|
||||
m_pendingAttachSize = 0;
|
||||
m_attachPreview->hide();
|
||||
m_pendingAttachAsVideo = false;
|
||||
}
|
||||
if (!text.isEmpty()) {
|
||||
emit sendMessage(text);
|
||||
@@ -326,21 +346,46 @@ void InputBar::onAttachClicked() {
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
QString ts = now.toString("yyyyMMdd-HHmmss");
|
||||
int rnd = rand() & 0xFFFF;
|
||||
QString destPath = QString("%1/%2_%3_%4.%5")
|
||||
.arg(mediaPath, ts).arg(fi.completeBaseName()).arg(rnd, 4, 16, QChar('0')).arg(fi.suffix().isEmpty() ? "bin" : fi.suffix());
|
||||
|
||||
bool asVideo = false;
|
||||
if (video_probe(srcPath.toUtf8().constData())) {
|
||||
QMessageBox box(this);
|
||||
box.setWindowTitle(QString::fromUtf8("Отправить видео"));
|
||||
box.setText(QString::fromUtf8("Файл содержит видео. Как отправить?"));
|
||||
QPushButton *fileBtn = box.addButton(QString::fromUtf8("Как файл"), QMessageBox::AcceptRole);
|
||||
QPushButton *videoBtn = box.addButton(QString::fromUtf8("Как видео"), QMessageBox::DestructiveRole);
|
||||
box.exec();
|
||||
asVideo = (box.clickedButton() == videoBtn);
|
||||
if (!box.clickedButton() || (!asVideo && box.clickedButton() != fileBtn)) {
|
||||
return; /* закрыт без выбора */
|
||||
}
|
||||
GUI_INFO("InputBar::onAttachClicked: video detected, mode=%s",
|
||||
asVideo ? "video" : "file");
|
||||
}
|
||||
|
||||
QString destPath;
|
||||
if (asVideo) {
|
||||
destPath = QString("%1/%2_%3_%4.mp4")
|
||||
.arg(mediaPath, ts).arg(fi.completeBaseName()).arg(rnd, 4, 16, QChar('0'));
|
||||
} else {
|
||||
destPath = QString("%1/%2_%3_%4.%5")
|
||||
.arg(mediaPath, ts).arg(fi.completeBaseName()).arg(rnd, 4, 16, QChar('0'))
|
||||
.arg(fi.suffix().isEmpty() ? "bin" : fi.suffix());
|
||||
}
|
||||
|
||||
m_pendingAttachSrc = srcPath;
|
||||
m_pendingAttachDest = destPath;
|
||||
m_pendingAttachName = fi.fileName();
|
||||
m_pendingAttachSize = fi.size();
|
||||
m_pendingAttachAsVideo = asVideo;
|
||||
|
||||
QString labelText = QString::fromUtf8("\xF0\x9F\x93\x8E %1 (%2)")
|
||||
.arg(fi.fileName(), formatFileSize(fi.size()));
|
||||
m_attachPreviewLabel->setText(labelText);
|
||||
m_attachPreview->show();
|
||||
|
||||
GUI_INFO("InputBar::onAttachClicked: pending %s size=%lld",
|
||||
qPrintable(srcPath), (long long)fi.size());
|
||||
GUI_INFO("InputBar::onAttachClicked: pending %s size=%lld video=%d",
|
||||
qPrintable(srcPath), (long long)fi.size(), asVideo ? 1 : 0);
|
||||
}
|
||||
|
||||
void InputBar::clearPendingAttachment() {
|
||||
@@ -348,9 +393,21 @@ void InputBar::clearPendingAttachment() {
|
||||
m_pendingAttachDest.clear();
|
||||
m_pendingAttachName.clear();
|
||||
m_pendingAttachSize = 0;
|
||||
m_pendingAttachAsVideo = false;
|
||||
m_videoProgressTimer->stop();
|
||||
m_attachPreview->hide();
|
||||
}
|
||||
|
||||
void InputBar::onVideoProgressTick() {
|
||||
int p = video_transcode_get_progress();
|
||||
if (p < 0) {
|
||||
m_videoProgressTimer->stop();
|
||||
m_attachPreview->hide();
|
||||
return;
|
||||
}
|
||||
m_attachPreviewLabel->setText(QString::fromUtf8("\xF0\x9F\x8E\xAC Перекодирование… %1%").arg(p / 10));
|
||||
}
|
||||
|
||||
void InputBar::resizeEvent(QResizeEvent* event) {
|
||||
QWidget::resizeEvent(event);
|
||||
if (m_recordOverlay) {
|
||||
|
||||
Reference in new issue
Block a user