|
| 1 | +#include "loopback.h" |
| 2 | + |
| 3 | +#include <iostream> |
| 4 | +#include <string> |
| 5 | +#include <sstream> |
| 6 | +#include <cwchar> |
| 7 | +#include <cstring> |
| 8 | +#include <chrono> |
| 9 | +#include <inttypes.h> |
| 10 | + |
| 11 | +#include "libKmpWebrtc.h" |
| 12 | + |
| 13 | +void* gPcClientFactory = nullptr; |
| 14 | +void* gPcClient = nullptr; |
| 15 | +PCClientCallback* gPcClientCallback = nullptr; |
| 16 | + |
| 17 | +static void pcClientFactoryErrorHandler(void*, int error, const char* message) { |
| 18 | + std::ostringstream oss; |
| 19 | + oss << "pcClientFactoryError code: " << error << ", message: " << message; |
| 20 | + LogInfo(oss.str().c_str()); |
| 21 | +} |
| 22 | + |
| 23 | +static const char* pcClientOnPreferCodecs(void*, const char* peer_uid, const char* sdp) { |
| 24 | + return sdp; |
| 25 | +} |
| 26 | + |
| 27 | +static void pcClientOnPeerConnectionStatsReady(void*, const char* peer_uid, const char* stats) { |
| 28 | + std::ostringstream oss; |
| 29 | + oss << "pcClientOnPeerConnectionStatsReady " << peer_uid << " " << stats; |
| 30 | + LogInfo(oss.str().c_str()); |
| 31 | +} |
| 32 | + |
| 33 | +static void pcClientOnIceDisconnected(void*, const char* peer_uid) { |
| 34 | +} |
| 35 | + |
| 36 | +static void pcClientOnError(void*, const char* peer_uid, int code) { |
| 37 | + std::ostringstream oss; |
| 38 | + oss << "pcClientError code: " << code; |
| 39 | + LogInfo(oss.str().c_str()); |
| 40 | +} |
| 41 | + |
| 42 | +static void pcClientOnLocalDescription(void*, const char* peer_uid, int type, const char* sdp); |
| 43 | +static void pcClientOnIceCandidate(void*, const char* peer_uid, const char* sdp_mid, int m_line_index, const char* sdp); |
| 44 | +static void pcClientOnIceConnected(void*, const char* peer_uid); |
| 45 | + |
| 46 | +void loopback(const char* path) { |
| 47 | + // 1. initialize |
| 48 | + InitializeWebRTC("", true); |
| 49 | + |
| 50 | + // 2. create gPcClientFactory |
| 51 | + PCClientFactoryConfig* config = DefaultPCClientFactoryConfig(); |
| 52 | + config->video_capture_impl = kKmpWebRTCCaptureFile; |
| 53 | + config->private_config.disable_encryption = 1; |
| 54 | + config->private_config.capture_file_path = path; |
| 55 | + gPcClientFactory = CreatePCClientFactory(config, pcClientFactoryErrorHandler, nullptr); |
| 56 | + PCClientFactoryConfigDestroy(&config); |
| 57 | + |
| 58 | + // 3. create local tracks |
| 59 | + CreateLocalTracks(gPcClientFactory); |
| 60 | + |
| 61 | + // 4. add local preview & start camera capture |
| 62 | + StartVideoCapture(gPcClientFactory); |
| 63 | + |
| 64 | + // 5. create PcClient |
| 65 | + gPcClientCallback = new PCClientCallback(); |
| 66 | + gPcClientCallback->on_prefer_codecs = pcClientOnPreferCodecs; |
| 67 | + gPcClientCallback->on_local_description = pcClientOnLocalDescription; |
| 68 | + gPcClientCallback->on_ice_candidate = pcClientOnIceCandidate; |
| 69 | + gPcClientCallback->on_stats_ready = pcClientOnPeerConnectionStatsReady; |
| 70 | + gPcClientCallback->on_ice_connected = pcClientOnIceConnected; |
| 71 | + gPcClientCallback->on_ice_disconnected = pcClientOnIceDisconnected; |
| 72 | + gPcClientCallback->on_error = pcClientOnError; |
| 73 | + gPcClient = CreatePeerConnectionClient(gPcClientFactory, "test", kKmpWebRTCDirSendRecv, 1, 800, 30, gPcClientCallback, nullptr); |
| 74 | + |
| 75 | + // 6. create pc |
| 76 | + CreatePeerConnection(gPcClient); |
| 77 | + |
| 78 | + // 7. create offer |
| 79 | + CreateOffer(gPcClient); |
| 80 | +} |
| 81 | + |
| 82 | +static void pcClientOnLocalDescription(void*, const char* peer_uid, int type, const char* sdp) { |
| 83 | + std::ostringstream oss; |
| 84 | + oss << "pcClientOnLocalDescription " << peer_uid << " " << sdp; |
| 85 | + LogInfo(oss.str().c_str()); |
| 86 | + // 8. send offer to remote, get answer from remote, and set answer |
| 87 | + SetRemoteDescription(gPcClient, kKmpWebRTCSdpAnswer, sdp); |
| 88 | +} |
| 89 | + |
| 90 | +static void pcClientOnIceCandidate(void*, const char* peer_uid, const char* sdp_mid, int m_line_index, const char* sdp) { |
| 91 | + std::ostringstream oss; |
| 92 | + oss << "pcClientOnIceCandidate " << peer_uid << " " << sdp; |
| 93 | + LogInfo(oss.str().c_str()); |
| 94 | + // 9. send ice candidate to remote, get ice candidate from remote, add ice candidate |
| 95 | + AddIceCandidate(gPcClient, sdp_mid, m_line_index, sdp); |
| 96 | +} |
| 97 | + |
| 98 | +static void pcClientOnIceConnected(void*, const char* peer_uid) { |
| 99 | + std::ostringstream oss; |
| 100 | + oss << "pcClientOnIceConnected " << peer_uid; |
| 101 | + LogInfo(oss.str().c_str()); |
| 102 | + |
| 103 | + // 10. on ice connected, add renderer for remote stream |
| 104 | + StartRecorder(gPcClient, kKmpWebRTCDirRecvOnly, "recv.mkv"); |
| 105 | +} |
0 commit comments