CURL CDVDInputStreamFFmpeg::GetM3UBestBandwidthStream(const CURL &url, size_t bandwidth) { typedef CPlayListM3U M3U; using std::string; using std::map; // we may be passed a playlist that does not contain playlists of different // bitrates (eg: this playlist is really the HLS video). So, default the // return to the filename so it can be played char szLine[4096]; string strLine; size_t maxBandwidth = 0; CCurlFile file; // set the proxy configuration const string host = GetProxyHost(); if (!host.empty()) file.SetProxy(GetProxyType(), host, GetProxyPort(), GetProxyUser(), GetProxyPassword()); // open the file, and if it fails, return if (!file.Open(url)) { file.Close(); return url; } // and set the fallback value CURL subStreamUrl(url); // determine the base CURL basePlaylistUrl(URIUtils::GetParentPath(url.Get())); basePlaylistUrl.SetOptions(""); basePlaylistUrl.SetProtocolOptions(""); const string basePart = basePlaylistUrl.Get(); // convert bandwidth specified in kbps to bps used by the m3u8 bandwidth *= 1000; while (file.ReadString(szLine, 1024)) { // read and trim a line strLine = szLine; StringUtils::Trim(strLine); // skip the first line if (strLine == M3U::StartMarker) continue; else if (StringUtils::StartsWith(strLine, M3U::StreamMarker)) { // parse the line so we can pull out the bandwidth const map< string, string > params = M3U::ParseStreamLine(strLine); const map< string, string >::const_iterator it = params.find(M3U::BandwidthMarker); if (it != params.end()) { const size_t streamBandwidth = atoi(it->second.c_str()); if ((maxBandwidth < streamBandwidth) && (streamBandwidth <= bandwidth)) { // read the next line if (!file.ReadString(szLine, 1024)) continue; strLine = szLine; StringUtils::Trim(strLine); // this line was empty if (strLine.empty()) continue; // store the max bandwidth maxBandwidth = streamBandwidth; // if the path is absolute just use it if (CURL::IsFullPath(strLine)) subStreamUrl = CURL(strLine); else subStreamUrl = CURL(basePart + strLine); } } } } // if any protocol options were set, restore them subStreamUrl.SetProtocolOptions(url.GetProtocolOptions()); return subStreamUrl; }