5G-MAG Reference Tools - MBMS Middleware
HlsMediaPlaylist.cpp
Go to the documentation of this file.
1 // 5G-MAG Reference Tools
2 // MBMS Middleware Process
3 //
4 // Copyright (C) 2021 Klaus Kühnhammer (Österreichische Rundfunksender GmbH & Co KG)
5 //
6 // Licensed under the License terms and conditions for use, reproduction, and
7 // distribution of 5G-MAG software (the “License”). You may not use this file
8 // except in compliance with the License. You may obtain a copy of the License at
9 // https://www.5g-mag.com/reference-tools. Unless required by applicable law or
10 // agreed to in writing, software distributed under the License is distributed on
11 // an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12 // or implied.
13 //
14 // See the License for the specific language governing permissions and limitations
15 // under the License.
16 //
17 
18 #include "HlsMediaPlaylist.h"
19 
20 #include "spdlog/spdlog.h"
21 #include "boost/algorithm/string.hpp"
22 #include <sstream>
23 
25 {
26  spdlog::debug("Parsing HLS media playlist: {}", content);
27 
28  std::istringstream iss(content);
29  int idx = 0;
30  int seq_nr = 0;
31  double extinf = -1;
32  for (std::string line; std::getline(iss, line); idx++ )
33  {
34  boost::algorithm::trim(line);
35 
36  if (idx==0) {
37  if ( line != "#EXTM3U") {
38  throw("HLS playlist parsing failed: first line is not #EXTM3U");
39  } else {
40  continue;
41  }
42  }
43 
44  size_t cpos = line.rfind(':');
45 
46  if (line.rfind("#EXT-X-VERSION", 0) == 0) {
47  if (_version != -1) {
48  throw("HLS playlist parsing failed: duplicate #EXT-X-VERSION");
49  }
50  if (cpos != std::string::npos) {
51  _version = atoi(line.substr(cpos+1).c_str());
52  }
53  } else if (line.rfind("#EXT-X-TARGETDURATION", 0) == 0) {
54  if (cpos != std::string::npos) {
55  _targetduration = atoi(line.substr(cpos+1).c_str());
56  }
57  } else if (line.rfind("#EXT-X-MEDIA-SEQUENCE", 0) == 0) {
58  if (cpos != std::string::npos) {
59  seq_nr = atoi(line.substr(cpos+1).c_str());
60  }
61  } else if (line.rfind("#EXTINF", 0) == 0) {
62  if (cpos != std::string::npos) {
63  extinf = atof(line.substr(cpos+1).c_str());
64  }
65  } else if (line.rfind('#', 0) == 0) {
66  spdlog::debug("HLS playlist parser ignoring unhandled line {}", line);
67  } else if (line.size() > 0) {
68  _segments.push_back({line, seq_nr++, extinf});
69  }
70  }
71 }
72 
73 
74 auto MBMS_RT::HlsMediaPlaylist::to_string() const -> std::string
75 {
76  std::stringstream pl;
77 
78  pl << "#EXTM3U" << std::endl;
79  pl << "#EXT-X-VERSION:3" << std::endl;
80 
81  if (_segments.size() > 0) {
82  pl << "#EXT-X-TARGETDURATION:" << _targetduration << std::endl;
83  pl << "#EXT-X-MEDIA-SEQUENCE:" << _segments[0].seq << std::endl;
84  }
85  for (const auto& seg : _segments) {
86  pl << "#EXTINF:" << seg.extinf << std::endl;
87  pl << "/" << seg.uri << std::endl;
88  }
89  return std::move(pl.str());
90 }
std::string to_string() const
std::vector< Segment > _segments