问题背景: 有些服务器,播放HLS时,m3u8文件经过gzip压缩,需要进行解压操作,否则无法播放。
使用curl的话则十分简单,可以在下载之前设置参数,curl会自己进行解压。参考源文档的解释,参数enc可以设置“gzip”或者“”即可(“”则支持更多的压缩方式)。
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_ACCEPT_ENCODING, char *enc);例子:
CURL *curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, "http://example.com"); /* enable all supported built-in compressions */ curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, ""); /* Perform the request */ curl_easy_perform(curl); }Three encodings are supported: identity, meaning non-compressed, deflate which requests the server to compress its response using the zlib algorithm, and gzip which requests the gzip algorithm. If a zero-length string is set like “”, then an Accept-Encoding: header containing all built-in supported encodings is sent.
参考: https://curl.haxx.se/libcurl/c/CURLOPT_ACCEPT_ENCODING.html
需要注意的点: 1、gzip格式使用inflate函数进行解压,而不是uncompress函数(uncompress是给zlib格式使用的)。 2、初始化函数必须使用inflateInit2(stream,47);
例子(截取一些调用代码):
(1)初始化: /* 15 is the max windowBits, +32 to enable optional gzip decoding */ if(inflateInit2(&s->b_inflate.stream, 32+15 ) != Z_OK ) { av_log(h, AV_LOG_ERROR, "Error during zlib initialisation: %s\n", s->b_inflate.stream.msg); } if(zlibCompileFlags() & (1<<17)) { av_log(h, AV_LOG_ERROR, "zlib was compiled without gzip support!\n"); } (2)解压: int ret; if(!s->b_inflate.p_buffer) { s->b_inflate.p_buffer = av_malloc(256*1024); } if(s->b_inflate.stream.avail_in == 0) { int i_read = http_read(h, s->b_inflate.p_buffer, 256*1024); if(i_read <= 0) return i_read; s->b_inflate.stream.next_in = s->b_inflate.p_buffer; s->b_inflate.stream.avail_in = i_read; } s->b_inflate.stream.avail_out = size; s->b_inflate.stream.next_out = buf; ret = inflate(&s->b_inflate.stream, Z_SYNC_FLUSH); (3)结束: inflateEnd(&s->b_inflate.stream); av_free(s->b_inflate.p_buffer);参考: gzip格式rfc 1952 http://www.ietf.org/rfc/rfc1952.txt deflate格式rfc 1951 http://www.ietf.org/rfc/rfc1951.txt zlib开发库 http://www.zlib.net/manual.html