You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
3.3 KiB
87 lines
3.3 KiB
/* Desktop publisher: GUI управляет источниками и AudioDevice, workers кодируют видео/Opus. |
|
* Окно не владеет трансляцией. Stop закрывает callbacks, joins workers и отправляет FIN. |
|
* Captured video/preview хранят только последний кадр; публикация использует общий C actor. */ |
|
#pragma once |
|
#include <QObject> |
|
#include <QTimer> |
|
#include <QVariant> |
|
#include <QImage> |
|
#include <QList> |
|
#include <QPointer> |
|
#include <QScreen> |
|
#include <memory> |
|
#include "live_video_encoder.h" |
|
#include "stream_video_modes.h" |
|
#include "audio_capture.h" |
|
#include "audio_capture_lease.h" |
|
#include "../../../src/stream/stream_publisher.h" |
|
|
|
struct StreamVideoSource { |
|
enum Kind { Camera, Screen, Window }; |
|
Kind kind = Camera; |
|
QString name; |
|
QByteArray id; |
|
QVariant window; |
|
QSize size; |
|
QList<StreamVideoMode> modes; |
|
QPointer<QScreen> screen; // Живой монитор; удаление устройства не должно переключать захват на его одноимённого соседа. |
|
bool sameSource(const StreamVideoSource& other) const { |
|
return kind == other.kind && id == other.id && window == other.window && screen == other.screen; |
|
} |
|
}; |
|
struct StreamPublishConfig { |
|
StreamVideoSource source; |
|
LiveVideoConfig video; |
|
QString microphone; |
|
bool audio = true; |
|
bool showCursor = true; |
|
bool nativeSize = false, automaticBitrate = false; |
|
}; |
|
class StreamPublishEngine : public QObject { |
|
Q_OBJECT |
|
public: |
|
explicit StreamPublishEngine(QObject* parent = nullptr); |
|
~StreamPublishEngine() override; |
|
bool start(uint64_t group, const StreamPublishConfig& config); |
|
bool reconfigure(const StreamPublishConfig& config); |
|
void stop(); |
|
bool active() const; |
|
bool running() const; |
|
uint64_t group() const; |
|
StreamPublishConfig config() const; |
|
QVariant previewFrame() const; |
|
QList<int> codecs() const; |
|
static QList<StreamVideoSource> sources(); |
|
static bool supported(); |
|
static bool cursorSupported(const StreamVideoSource& source); |
|
void setMuted(bool muted); |
|
bool muted() const; |
|
uint64_t softwareEncodingRequest() const; |
|
void answerSoftwareEncoding(uint64_t generation, bool allow); |
|
signals: |
|
void codecsChanged(); |
|
void sourcesChanged(); |
|
void stateChanged(const QString& state); |
|
void configurationChanged(); |
|
void previewVideoChanged(const QVariant& frame); |
|
void telemetryChanged(const stream_publisher_status& status); |
|
void errorOccurred(const QString& error); |
|
void audioChannelsChanged(int channels); |
|
void softwareEncodingRequested(uint64_t generation, const QString& codec, const QString& details); |
|
private: |
|
struct Impl; |
|
std::unique_ptr<Impl> m; |
|
AudioCapture m_capture; |
|
AudioCaptureLease m_microphone{AudioCaptureLease::Mode::Exclusive}; |
|
QTimer m_timer; |
|
QTimer m_previewTimer; |
|
bool openSource(const StreamPublishConfig& config); |
|
void closeSource(); |
|
bool openMicrophone(); |
|
void sourceFailed(uint64_t generation, const QString& error); |
|
void publicationFailed(uint64_t id, const QString& error); |
|
void tick(); |
|
void videoLoop(StreamPublishConfig initial); |
|
void audioLoop(); |
|
void captureAudio(const AudioCapture::Frame& frame); |
|
};
|
|
|