+
+ if (fragments[i].begins_header) {
+ // End of this group. (We've already printed the header
+ // as part of the previous group.)
+ printed_header_for_this_group = false;
+ continue;
+ }
+ if (!printed_header_for_this_group) {
+ // Look forward until we find the header for this group (if any).
+ for (size_t j = i + 1; j < fragments.size() - 1; ++j) {
+ if (fragments[j].begins_header) {
+ if (printed_first_header) {
+ playlist += "#EXT-X-DISCONTINUITY\r\n";
+ }
+ snprintf(buf, sizeof(buf),
+ "#EXT-X-MAP:URI=\"%s?frag=%" PRIu64 "-%" PRIu64 "\"\r\n",
+ url.c_str(), fragments[j].byte_position,
+ fragments[j + 1].byte_position);
+ playlist += buf;
+ printed_first_header = true;
+ printed_header_for_this_group = true;
+ break;
+ }
+ }
+
+ if (!printed_header_for_this_group && !stream_header.empty()) {
+ if (printed_first_header) {
+ playlist += "#EXT-X-DISCONTINUITY\r\n";
+ }
+ snprintf(buf, sizeof(buf), "#EXT-X-MAP:URI=\"%s?frag=header\"\r\n", url.c_str());
+ playlist += buf;
+ }
+
+ // Even if we didn't find anything, we don't want to search again for each fragment.
+ printed_first_header = true;
+ printed_header_for_this_group = true;
+ }
+
+ if (fragments[i + 1].begins_header) {
+ // Since we only have start pts for each block and not duration,
+ // we have no idea how long this fragment is; the encoder restarted
+ // before it got to output the next pts. However, it's likely
+ // to be very short, so instead of trying to guess, we just skip it.
+ continue;
+ }
+
+ snprintf(buf, sizeof(buf), "#EXTINF:%f,\r\n%s?frag=%" PRIu64 "-%" PRIu64 "\r\n",