1 /*
2  * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <condition_variable>
17 #include <memory>
18 #include <mutex>
19 #include <sstream>
20 #include "rtsp_client.h"
21 #include "sharing_log.h"
22 
23 using namespace OHOS::Sharing;
24 
main()25 int main()
26 {
27     auto rtspClient = std::make_shared<RtspClient>();
28     std::vector<SdpTrack::Ptr> medias;
29     uint32_t trackIndex = 0;
30     std::mutex mutex;
31     std::condition_variable signal;
32     rtspClient->SetUrl("rtsp://wowzaec2demo.streamlock.net:554/vod/mp4:BigBuckBunny_115k.mp4");
33     rtspClient->SetOnRecvRtspPacket([&](const std::string &method, const RtspMessage &rsp) {
34         if (method == "OPTION") {
35             auto err = rtspClient->HandleOptionRsp(rsp);
36             switch (err) {
37                 case RtspRspResult::RSP_UNAUTHED:
38                     rtspClient->SendOption();
39                     break;
40                 case RtspRspResult::RSP_OK: {
41                     std::stringstream ss;
42                     ss << "v=0"
43                        << "\r\n";
44                     ss << "o=- 0 0 IN IP4 127.0.0.1"
45                        << "\r\n";
46                     ss << "s=No Name"
47                        << "\r\n";
48                     ss << "c=IN IP4 192.168.159.128"
49                        << "\r\n";
50                     ss << "t=0 0"
51                        << "\r\n";
52                     ss << "a=tool:libavformat 59.17.101"
53                        << "\r\n";
54                     ss << "m=video 0 RTP/AVP 96"
55                        << "\r\n";
56                     ss << "a=rtpmap:96 H264/90000"
57                        << "\r\n";
58                     ss << "a=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z0LAKIyNQDwDTf+A0ADRgPCIRqA=,aM48gA==; profile-level-id=42C028"
59                        << "\r\n";
60                     ss << "a=control:streamid=0"
61                        << "\r\n";
62                     ss << "m=audio 0 RTP/AVP 97"
63                        << "\r\n";
64                     ss << "b=AS:128"
65                        << "\r\n";
66                     ss << "a=rtpmap:97 MPEG4-GENERIC/44100/2"
67                        << "\r\n";
68                     ss << "a=fmtp:97 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3; config=121056E500"
69                        << "\r\n";
70                     ss << "a=control:streamid=1"
71                        << "\r\n";
72                     rtspClient->SetSdp(ss.str());
73                     rtspClient->SendAnnounce();
74                     break;
75                 }
76                 default: {
77                     SHARING_LOGE("setOnRecvRtspPacket ret err");
78                     signal.notify_one();
79                     break;
80                 }
81             }
82 
83         } else if (method == "ANNOUNCE") {
84             auto err = rtspClient->HandleAnnounceRsp(rsp);
85             switch (err) {
86                 case RtspRspResult::RSP_UNAUTHED:
87                     rtspClient->SendAnnounce();
88                     break;
89                 case RtspRspResult::RSP_OK: {
90                     auto mediaTemp = rtspClient->GetAllMedia();
91                     for (auto media : mediaTemp) {
92                         medias.emplace_back(media);
93                     }
94                     rtspClient->SendSetup(trackIndex++);
95                     break;
96                 }
97                 default: {
98                     SHARING_LOGE("setOnRecvRtspPacket ret err");
99                     signal.notify_one();
100                     break;
101                 }
102             }
103         } else if (method == "SETUP") {
104             rtspClient->HandleSetupRsp(rsp);
105             auto err = rtspClient->HandleDescribeRsp(rsp);
106             switch (err) {
107                 case RtspRspResult::RSP_OK:
108                     if (trackIndex < medias.size() - 1) {
109                         rtspClient->SendSetup(trackIndex++);
110                     } else {
111                         rtspClient->SendPlay();
112                         trackIndex = 0;
113                     }
114                     break;
115                 default: {
116                     SHARING_LOGE("setOnRecvRtspPacket ret err");
117                     signal.notify_one();
118                 } break;
119             }
120         } else if (method == "RECORD") {
121             rtspClient->HandlePlayRsp(rsp);
122             signal.notify_one();
123         }
124     });
125     rtspClient->SetExceptionCb([&](const RtspExceptType except) {
126         SHARING_LOGE("onRtspException err");
127         signal.notify_one();
128     });
129 
130     rtspClient->SetRtspReadyCb([&]() { rtspClient->SendOption(); });
131 
132     if (!rtspClient->Open()) {
133         SHARING_LOGE("openRtspClient err");
134         return 0;
135     }
136     std::unique_lock<std::mutex> lk(mutex);
137     signal.wait(lk);
138     return 0;
139 };