www.jianshu.com Open in urlscan Pro
79.133.177.218  Public Scan

URL: https://www.jianshu.com/p/da2176382af5
Submission: On February 02 via manual from US — Scanned from DE

Form analysis 0 forms found in the DOM

Text Content

登录注册写文章
首页下载APP会员IT技术



使用代理解决跨域直播源M3U8播放问题

GDUF_XRT关注赞赏支持



使用代理解决跨域直播源M3U8播放问题

GDUF_XRT关注IP属地: 广东
0.1782019.05.21 03:07:13字数 352阅读 24,735


问题描述

使用 videojs 播放 cctv
直播源(http://cctvcnch5c.v.wscdns.com/live/cctv13_2/index.m3u8)时,出现跨域问题,如下所示:

Access to XMLHttpRequest at 'http://cctvcnch5c.v.wscdns.com/live/cctv13_2/index.m3u8' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.



解决思路

跨域限制在 cctvcnch5c.v.wscdns.com 上,无法通过配置服务器解决限制。只能通过中间层接口请求或代理进行绕过(服务器访问不受跨域协议限制)。


解决过程

中间层使用 express 框架,代理插件可使用 express-http-proxy。

m3u8 直播源解析过程为如下:

 1. 请求 m3u8 播放源地址
 2. 服务端返回 m3u8 纯文本索引文件,其中包含各个媒体段的 url
 3. 客户端解析 m3u8 的播放列表,再按序请求每一段的url,获取ts数据流

其中,服务端返回的媒体段地址为相对地址,默认前缀路径为步骤1的 m3u8
的请求路径,所以还需要对步骤1返回的数据做处理,即步骤1需要使用接口模式,而步骤3使用代理模式(express-http-proxy)。

具体代码如下:

// main.js

var express = require('express');
var proxy = require('express-http-proxy');
var router = express.Router();
var urlParse = require('url').parse;
var controller = require('./controller.js');
// 代理直播源
router.get('/videos', controller.videoProxy);
router.use(
  '/tsProxy',
  proxy(
    function(req) {
      var target = urlParse(decodeURIComponent(req.query.url))
      return target.host
    },
    {
      parseReqBody: false, // 去除默认的 body,解决某些播放源 411 问题
      proxyReqPathResolver: function(req) {
        var target = urlParse(decodeURIComponent(req.query.url))
        return target.path
      },
    }
  )
)


> express-http-proxy 默认自动解析并设置 req.body,这将导致 cctv 服务器识别到没有 content-length 头部的
> request body,并返回 411 错误码。所以需要在中间件配置上将 parseReqBody 设置为false。

// controller.js

var axios = require('axios')
var controller = {};

controller.videoProxy = function(req, res) {
  try {
    var url = decodeURIComponent(req.query.url)
    var parseUrl = urlParse(url)
    var domain = parseUrl.protocol + '//' + parseUrl.host // http 域名地址
    var m3u8Path = url.match(/\S+\//)[0] // http 至最后一个 '/' 字符
    axios
      .get(url)
      .then(resp => {
        var headers = resp.headers
        var content = resp.data
        // 内容为 ts 文件地址则使用 tsProxy 的 path
        var path = /BANDWIDTH/i.test(content)
          ? '/school/videos?url='
          : '/school/tsProxy?url='

        // 头部信息全部返回
        for (var key in headers) {
          res.append(key, headers[key])
        }

        // 对 data 中目标文件字符串做处理
        content = content.replace(/(?:\n)([^# \n]+\.\S+)/g, function(_, match) {
          // 绝对地址,不做任何修改
          if (/^http/.test(match)) {
            return '\n' + path + encodeURIComponent(match)
          }
          // 相对地址:有文件结构的相对地址直接加域名,否则加上带 path 的域名
          return (
            '\n' +
            path +
            encodeURIComponent((/^\//g.test(match) ? domain : m3u8Path) + match)
          )
        })
        res.send(content)
      })
      .catch(e => {
        res.json({
          code: (e.response && e.response.status) || 404,
          message: e.message || '',
          success: false
        })
      })
  } catch (e) {
    res.json({
      code: 400,
      message: 'URI must be not empty!',
      success: false
    })
  }
}
module.exports = controller;




2人点赞

工作总结


更多精彩内容,就在简书APP


"小礼物走一走,来简书关注我"
赞赏支持还没有人赞赏,支持一下
GDUF_XRT
总资产2共写了1.0W字获得14个赞共5个粉丝
关注




推荐阅读更多精彩内容

 * express 4.x Api 中文版-最新中文详细解释
   Address:https://www.zybuluo.com/XiangZhou/note/208532 Exp...
   天蠍蒗漫阅读 10,628评论 2赞 55
 * github地址,欢迎大家提交更新。
   github地址,欢迎大家提交更新。 express() express()用来创建一个Express的程序。ex...
   Programmer客栈阅读 2,104评论 0赞 1
 * 详解跨域
   什么是跨域 跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实...
   Yaoxue9阅读 1,121评论 0赞 6
 * 详解跨域
   什么是跨域 跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实...
   他方l阅读 933评论 0赞 2
 * 我们在努力,请宽容这份努力
   多少时间了,大女儿都没有主动来要求我去为她做点事。今天她打破了这个沉默,就在晚饭吃完以后,我坐在客厅的沙发上休息,...
   耶楚雅南阅读 525评论 3赞 10
 * 一朵美丽绽放的绿色曼陀罗
   文/花语-蝴蝶兰之语 周日参加了萨提亚自我成长工作坊,老师给每一个人留了一个作业:完成自我曼陀罗。每个人领到八张彩...
   花语_蝴蝶兰之语阅读 852评论 2赞 8
 * 这样的规则要不得
   甘德礼(这样的规则要不得)持续原创分享第416天,挑战光山心协读书分享365天第四十六天 今天接待一位小患者,女孩...
   华南帝虎阅读 163评论 0赞 1

GDUF_XRT
关注
总资产2

js中的协程
阅读 1,677
linux 上使用 npm 安装 gifsicle 报错问题
阅读 5,911


热门故事

小心!白月光有毒
必看!全网点赞超10w+的短篇脑洞甜文!
女明星穿越假扮太子,皇帝老爹还不知道我是女儿身!
基因改良,从现在开始人类也可以个性定制!
我拒绝过的男人成了我家的救命稻草…


推荐阅读

浏览器同源策略&跨域问题
阅读 158
539.【博客开发】前后端联调,接入 grpc 登录接口
阅读 331
使用FastAPI进行URL重定向
阅读 348
apache 里的 ProxyPassReverse 指令
阅读 179
Android 边播放边缓存视频框架AndroidVideoCache简析
阅读 64

评论4
赞2


2赞3赞
赞赏
更多好文