libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
rtmpsession.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_NETWORK
13#include <cstdint>
14
15#include <promeki/amf0.h>
16#include <promeki/atomic.h>
17#include <promeki/enums.h>
18#include <promeki/error.h>
19#include <promeki/fourcc.h>
20#include <promeki/hashmap.h>
21#include <promeki/list.h>
22#include <promeki/metadata.h>
23#include <promeki/mutex.h>
24#include <promeki/namespace.h>
25#include <promeki/objectbase.h>
26#include <promeki/result.h>
29#include <promeki/rtmpmessage.h>
30#include <promeki/string.h>
31
32PROMEKI_NAMESPACE_BEGIN
33
34class IODevice;
35
47struct RtmpConnectOptions {
49 String app;
51 String tcUrl;
53 String pageUrl;
55 String swfUrl;
57 String flashVer;
59 String type = "nonprivate";
61 int objectEncoding = 0;
63 int capabilities = 239;
65 int audioCodecs = 0x0FFF;
67 int videoCodecs = 0x00FF;
69 int videoFunction = 1;
80 List<FourCC> fourCcList = { FourCC("hvc1") };
81};
82
138class RtmpSession : public ObjectBase {
139 PROMEKI_OBJECT(RtmpSession, ObjectBase)
140 public:
142 static constexpr int DefaultPostConnectChunkSize = 60000;
143
151 explicit RtmpSession(RtmpRole role, ObjectBase *parent = nullptr);
152
154 ~RtmpSession() override;
155
163 Error attach(IODevice *device);
164
166 IODevice *device() const { return _device; }
167
169 RtmpChunkStream *chunkStream() { return _chunk.get(); }
170
177 Error performHandshake(unsigned int timeoutMs = 10000);
178
179 // ----- High-level commands (client side) -----
180
193 Error connect(const RtmpConnectOptions &opts, unsigned int timeoutMs = 10000);
194
199 Result<uint32_t> createStream(unsigned int timeoutMs = 5000);
200
209 Error publish(uint32_t streamId, const String &streamKey,
210 const String &mode = "live", unsigned int timeoutMs = 5000);
211
224 Error play(uint32_t streamId, const String &streamKey,
225 double start = -2.0, double duration = -1.0,
226 unsigned int timeoutMs = 5000);
227
233 Error deleteStream(uint32_t streamId);
234
243 Error releaseStream(const String &streamKey);
244
250 Error fcPublish(const String &streamKey);
251
256 Error fcUnpublish(const String &streamKey);
257
263 Error fcSubscribe(const String &streamKey);
264
265 // ----- Raw access -----
266
272 Error sendMessage(const RtmpMessage &m);
273
286 Result<RtmpMessage> readMessage(unsigned int timeoutMs = 0);
287
297 static Error onStatusToError(const String &code);
298
299 // ----- Signals -----
300
302 PROMEKI_SIGNAL(handshakeComplete);
303
305 PROMEKI_SIGNAL(connected);
306
312 PROMEKI_SIGNAL(connectionFailed, Error);
313
319 PROMEKI_SIGNAL(streamCreated, uint32_t);
320
326 PROMEKI_SIGNAL(publishStarted, uint32_t);
327
333 PROMEKI_SIGNAL(playStarted, uint32_t);
334
343 PROMEKI_SIGNAL(onStatus, Amf0Value);
344
351 PROMEKI_SIGNAL(onMetaData, Metadata);
352
358 PROMEKI_SIGNAL(audioMessageReceived, RtmpMessage);
359
365 PROMEKI_SIGNAL(videoMessageReceived, RtmpMessage);
366
368 PROMEKI_SIGNAL(disconnected);
369
370 private:
372 struct PendingTransaction {
373 Error result = Error::Timeout;
374 bool completed = false;
375 Amf0Value commandObject;
376 Amf0Value info;
391 uint32_t expectedMsid = 0;
399 String commandName;
400 };
401
402 Error sendCommand(uint32_t csid, uint32_t msid,
403 const String &command, double txnId,
404 const Amf0Value::List &args);
405 Error awaitTransaction(double txnId, unsigned int timeoutMs,
406 PendingTransaction *outTxn = nullptr);
407 Error handleInboundCommand(const RtmpMessage &msg);
408 Error handleInboundUserControl(const RtmpMessage &msg);
409 Error handleInboundData(const RtmpMessage &msg);
410 void applyConnectFlowDefaults();
411
417 Error pumpUntilTransaction(double txnId, unsigned int timeoutMs,
418 PendingTransaction *outTxn);
419
421 double nextTransactionId();
422
423 IODevice *_device = nullptr;
424 RtmpRole _role;
425 RtmpHandshake _handshake;
426 UniquePtr<RtmpChunkStream> _chunk;
427
428 Atomic<double> _nextTxnId{1.0};
429
430 Mutex _txnMutex;
431 HashMap<double, PendingTransaction *> _pending;
432
433 bool _connected = false;
434};
435
436PROMEKI_NAMESPACE_END
437
438#endif // PROMEKI_ENABLE_NETWORK