前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >IOS支持音频流断点续传

IOS支持音频流断点续传

原创
作者头像
lainzhang
发布2022-08-24 19:17:23
1.1K0
发布2022-08-24 19:17:23
举报
文章被收录于专栏:lainzhang的专栏

导语:

使用c++实现音频流过程中遇到的问题和解决过程

步骤一 :

在使用cgi编写输出音频流接口,前端同事无法拖动播放,于是查阅资料找到了一个关键词:断点续传 断点续传的解释: 断点续传:指的是在上传/下载时,将任务(一个文件或压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传/下载,如果碰到网络故障,可以从已经上传/下载的部分开始继续上传/下载未完成的部分,而没有必要从头开始上传/下载。可以节省时间,提高速度。 断点续传的用途: 有时用户上传/下载文件需要历时数小时,万一线路中断,不具备断点续传的 HTTP/FTP 服务器或下载软件就只能从头重传,比较好的 HTTP/FTP 服务器或下载软件具有断点续传能力,允许用户从上传/下载断线的地方继续传送,这样大大减少了用户的烦恼。 常见的支持断点续传的上传/下载软件:QQ 旋风、迅雷、快车、电驴、酷6、土豆、优酷、百度视频、新浪视频、腾讯视频、百度云等。 HTTP1.1 协议(RFC2616)开始支持获取文件的部分内容,这为并行下载以及断点续传提供了技术支持。它通过在 Header 里两个参数实现的,客户端发请求时对应的是 Range ,服务器端响应时对应的是 Content-Range。 解决方案: 在返回标头中新增两个参数 printf("Content-Length: %ld\n", file_size); printf("Content-Range: bytes 0-%ld/%ld\n", file_size - 1, file_size); 这里我将文件长度和范围都返回给前端,实现了拖动播放。

步骤二:

发现chrome和android机器都可以实现拖动,但iOS和safari中无法拖动播放,一度以为是前端同学播放组件有问题,后面发现,其实不然! 查阅资料: 通过比较Chrome和Safari的请求我们发现,Chrome请求头中range字段的值是bytes=0-,而Safari请求头中range字段的值是bytes=0-1。从此得知,浏览器请求音频时是使用的范围请求,Chrome是用一个HTTP请求请求了整个音频,即请求音频的第0个字节到最后一个字节,Chrome不强制要求服务端支持范围请求,服务端响应200或206,Chrome都能支持。但是Safari要求服务端必须支持范围请求,Safari会先请求音频的第0个字节到第1个字节,来测试服务端是否支持范围请求,如果服务端支持范围请求,则响应状态码206,响应头中有正确的Content-Range字段,响应体是音频的第一个字节,此时,Safari才会继续请求音频的其他字节,否则Safari会放弃该音频的请求。我们音频的服务端不支持范围请求,响应的是整个音频,状态码200,所以导致无法在Safari播放。 解决方案: 当收到请求表头有range的时候,返回部分文件流,否则返回全部。

参考代码:

代码语言:javascript
复制
       // 文件校验
        size_t file_size;
        string filename = file_path + audio;
        SysLog(INFO, "PID[%d] FILENAME: %s", PID, filename.c_str());
        ifstream in(filename, ios::in | ios::binary | ios::ate);
        in.seekg(0, std::ios::end);
        file_size = in.tellg();
        
        SysLog(INFO, "PID[%d] FILE_SIZE: %ld", PID, file_size);
        if ((int)file_size < 0)
        {
            in.close();
            SysLog(ERROR, "PID[%d] file error", PID);
            write_msg_json(-4, "read file error", NULL, NULL);
            return 0;
        }

        CallLibcurl libcurl;
        verifyUrl(audioUrl);
        string header = "";
        int start = 0;
        int end = file_size - 1;

        char *HTTP_RANGE = getenv("HTTP_RANGE");
        SysLog(INFO, "PID[%d] REQ_ENV: HTTP_RANGE:%s", PID, HTTP_RANGE);

        //ios特殊处理 需要支持断点续传
        if (HTTP_RANGE != NULL)
        {
            string HTTP_RANGE_STRING = HTTP_RANGE;
            HTTP_RANGE_STRING = HTTP_RANGE_STRING.substr(6);

            vector<string> list1;
            list1 = split(HTTP_RANGE_STRING, "-");
            start = atoi(list1[0].c_str());
            if (list1.size() > 1)
            {
                end = atoi(list1[1].c_str());
            }
            else
            {
                end = start + 99999999;
                end = end > file_size - 1 ? file_size - 1 : end;
            }
            printf("Status:206\n");
            printf("Content-Length: %ld\n", (end - start) + 1);
            printf("Content-Range: bytes %ld-%ld/%ld\n", start, end, file_size);
        }
        else
        {
            printf("Status:200\n");
            printf("Content-Length: %ld\n", file_size);
            printf("Content-Range: bytes 0-%ld/%ld\n", file_size - 1, file_size);
        }
        printf("Accept-Ranges: bytes\n");
        printf("Content-Type: audio/mpeg\n\n");

        int content_length = 0;
        char *val;
        in.seekg(start);
        content_length = end - start + 1;
        char *buf = new char[content_length];
        in.read(buf, content_length);
        for(size_t i = 0; i < content_length;i++){
            char temp = buf[i];
            Content += temp;
        }
        in.close();
        SysLog(INFO, "PID[%d] LEN: %ld", PID, content_length);
        cout.write(Content.c_str(), content_length);

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导语:
  • 步骤一 :
  • 步骤二:
  • 参考代码:
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档