Skip to content

Commit

Permalink
Solved problems with hlsstream
Browse files Browse the repository at this point in the history
  • Loading branch information
lanstat committed May 14, 2024
1 parent c2bca27 commit bcc0fd3
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 18 deletions.
68 changes: 53 additions & 15 deletions src/HLSStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@
#define CHANNEL_INNER_TAG 0x05
#define SEGMENT_INNER_PLAYLIST_TAG 0x06

#define REMAINING_FETCHES 20
#define REMAINING_FETCHES 10
#define MAX_TRACKS_PER_PLAYLIST 4

#define TIMEOUT_TRACK 15000
#define TRACK_DELTA 150

HLSStream::HLSStream() {}

Expand Down Expand Up @@ -121,7 +122,8 @@ void HLSStream::ProcessChannel(struct Mux *mux, struct iovec *buffer, int size,
std::string path =
url.replace(url.begin(), url.begin() + 7, "/");
path = path.substr(path.find("/", 1));
Log(__FILE__, __LINE__, Log::kDebug) << "Found playlist: " << path;
Log(__FILE__, __LINE__, Log::kDebug)
<< "Found playlist: " << path;

uint64_t resource_id = parent_id;

Expand Down Expand Up @@ -166,10 +168,13 @@ bool HLSStream::ProcessSegmentList(uint64_t parent_id, struct iovec *buffer,
}
playlist->remaining_fetches--;

long epoch_ms = Helpers::GetTicks();
int timeout = 0;

long last_stamp = playlist->last_stamp;
if (last_stamp == 0) {
last_stamp = Helpers::GetTicks() + TRACK_DELTA;
}
int sequence = 0;
bool found = false;

for (int i = 0; i < size; i++) {
if (buffer[i].iov_len == 0) continue;
std::string content((char *)buffer[i].iov_base);
Expand All @@ -186,8 +191,8 @@ bool HLSStream::ProcessSegmentList(uint64_t parent_id, struct iovec *buffer,
seconds.erase(std::remove(seconds.begin(), seconds.end(), '.'),
seconds.end());
auto stamp = std::stoi(seconds);
timeout += stamp;
uint64_t uid = Helpers::GetResourceId(url.c_str());
sequence++;

if (std::find(playlist->track_uids.begin(),
playlist->track_uids.end(),
Expand All @@ -198,23 +203,36 @@ bool HLSStream::ProcessSegmentList(uint64_t parent_id, struct iovec *buffer,
std::string tmp = url;

tmp = tmp.replace(tmp.begin(), tmp.begin() + 7, "/");
Log(__FILE__, __LINE__) << "Found TS: " << tmp;
//Log(__FILE__, __LINE__) << "Found TS: " << tmp;
Log(__FILE__, __LINE__) << "Found TS: " << last_stamp;

int pos = url.find(Settings::Proxy);
if (pos != std::string::npos) {
url.replace(pos, Settings::Proxy.length(), Settings::BaseUrl);
}

std::string block = line + "\n" + url + "\n";
playlist->track_stamps.push_back(epoch_ms + timeout);
playlist->track_stamps.push_back(last_stamp);
playlist->track_uids.push_back(uid);
playlist->track_urls.push_back(block);
playlist->sequence++;
playlist->track_sequence.push_back(sequence);

last_stamp += stamp;
}
} else if (line.rfind("#EXT-X-MEDIA-SEQUENCE:", 0) == 0) {
std::string tmp = line.substr(22);
sequence = std::stoi(tmp);
sequence--;
continue;
}
}
}

if (playlist->last_stamp != last_stamp) {
playlist->last_stamp = last_stamp;
CleanTracks(playlist);
}

if (!found) {
RequestFile(playlist->resource_id, playlist->url, CHANNEL_INNER_TAG, 500);
} else {
Expand All @@ -231,7 +249,7 @@ void HLSStream::CreatePlaylist(uint64_t resource_id, uint64_t channel_id,
playlist->channel_id = channel_id;
playlist->url = channel_url;
playlist->remaining_fetches = REMAINING_FETCHES;
playlist->sequence = 10000;
playlist->last_stamp = 0;
playlists_.insert(
std::pair<uint64_t, struct SegmentPlaylist *>(resource_id, playlist));

Expand Down Expand Up @@ -323,20 +341,21 @@ void HLSStream::GenerateSegmentClientList(uint64_t resource_id,
ss << "#EXTM3U\r\n";
ss << "#EXT-X-VERSION:3\r\n";
ss << "#EXT-X-TARGETDURATION:3\r\n";
ss << "#EXT-X-MEDIA-SEQUENCE:" << playlist->sequence << "\r\n";

// Only copy the tracks that are after the current ticks
int pivot = 0;
const std::vector<long> &stamps = playlist->track_stamps;
for (int i = 0; i < stamps.size(); i++) {
if (stamps[i] > ticks) {
pivot = i;
if (pivot > 0) {
pivot--;
}
// if (pivot > 0) {
// pivot--;
//}
break;
}
}
ss << "#EXT-X-MEDIA-SEQUENCE:" << playlist->track_sequence.at(pivot)
<< "\r\n";
const std::vector<std::string> &urls = playlist->track_urls;
for (int i = 0; i < MAX_TRACKS_PER_PLAYLIST; i++) {
if ((pivot + i) >= urls.size()) {
Expand Down Expand Up @@ -391,7 +410,8 @@ void HLSStream::RemoveSegment(uint64_t resource_id) {
void HLSStream::UpdateHeader(struct Mux *mux, int content_length) {
std::string header((char *)mux->header.iov_base);

header = Utils::ReplaceHeaderTag(header, "Content-Length", std::to_string(content_length));
header = Utils::ReplaceHeaderTag(header, "Content-Length",
std::to_string(content_length));
if (mux->header.iov_len > 0) {
free(mux->header.iov_base);
}
Expand All @@ -400,3 +420,21 @@ void HLSStream::UpdateHeader(struct Mux *mux, int content_length) {
memset(mux->header.iov_base, 0, mux->header.iov_len);
memcpy(mux->header.iov_base, (void *)header.c_str(), header.size());
}

void HLSStream::CleanTracks(struct SegmentPlaylist *playlist) {
if (playlist->track_urls.size() < 10) {
return;
}

int count = playlist->track_urls.size() - 10;
std::cout<< "LAN_[" << __FILE__ << ":" << __LINE__ << "] "<< count << std::endl;

playlist->track_urls.erase(playlist->track_urls.begin(),
playlist->track_urls.begin() + count);
playlist->track_uids.erase(playlist->track_uids.begin(),
playlist->track_uids.begin() + count);
playlist->track_stamps.erase(playlist->track_stamps.begin(),
playlist->track_stamps.begin() + count);
playlist->track_sequence.erase(playlist->track_sequence.begin(),
playlist->track_sequence.begin() + count);
}
5 changes: 3 additions & 2 deletions src/HLSStream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ class HLSStream : public Stream {
uint64_t resource_id;
uint64_t channel_id;
int remaining_fetches;
int sequence;
long last_stamp;
std::string url;
std::vector<std::string> track_urls;
std::vector<uint64_t> track_uids;
std::vector<long> track_stamps;
std::vector<int> track_sequence;
};

std::unordered_map<uint64_t, struct SegmentPlaylist *> playlists_;
Expand All @@ -32,7 +33,6 @@ class HLSStream : public Stream {
void ProcessChannel(struct Mux *mux, struct iovec *buffer, int size, uint64_t parent_id, struct iovec *new_buffer);
bool ProcessSegmentList(uint64_t parent_id, struct iovec *buffer, int size);
void CreatePlaylist(uint64_t resource_id, uint64_t channel_id, std::string channel_url);
void AppendSegments();
void RequestPlaylist(uint64_t resource_id, std::string url);
void RequestFile(uint64_t parent_id, std::string url, int tag, int msecs = 0);

Expand All @@ -42,6 +42,7 @@ class HLSStream : public Stream {
void RemoveSegment(uint64_t resource_id);
void RemovePlaylist(uint64_t resource_id);
void UpdateHeader(struct Mux *mux, int content_length);
void CleanTracks(struct SegmentPlaylist *playlist);

};
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/Stream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class Stream {
struct Mux *GetResource(uint64_t resource_id);
bool ExistsResource(uint64_t resource_id);

void HandleCleanup(struct Request *request);
virtual void HandleCleanup(struct Request *request);

protected:
struct io_uring *ring_;
Expand Down

0 comments on commit bcc0fd3

Please sign in to comment.