| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- /**
- * 媒体工具类 - 处理视频流地址转换
- */
- // 流协议类型
- export const STREAM_PROTOCOLS = {
- RTMP: 'rtmp://',
- HTTP_FLV: ['http://', 'https://'],
- HLS: ['http://', 'https://'],
- WS_FLV: ['ws://', 'wss://']
- }
- /**
- * 判断视频流类型
- * @param {String} url 视频流地址
- * @returns {String} 流类型,如 'rtmp', 'http-flv', 'hls', 'ws-flv'
- */
- export const getStreamType = (url) => {
- if (!url) return null
-
- const lowerUrl = url.toLowerCase()
-
- if (lowerUrl.startsWith(STREAM_PROTOCOLS.RTMP)) {
- return 'rtmp'
- }
-
- if (STREAM_PROTOCOLS.HTTP_FLV.some(protocol => lowerUrl.startsWith(protocol)) && lowerUrl.endsWith('.flv')) {
- return 'http-flv'
- }
-
- if (STREAM_PROTOCOLS.HLS.some(protocol => lowerUrl.startsWith(protocol)) &&
- (lowerUrl.endsWith('.m3u8') || lowerUrl.includes('.m3u8?'))) {
- return 'hls'
- }
-
- if (STREAM_PROTOCOLS.WS_FLV.some(protocol => lowerUrl.startsWith(protocol)) &&
- (lowerUrl.endsWith('.flv') || lowerUrl.includes('.flv?') || lowerUrl.includes('live.flv'))) {
- return 'ws-flv'
- }
-
- return 'unknown'
- }
- /**
- * 检查流是否在小程序中可播放
- * @param {String} url 视频流地址
- * @returns {Boolean} 是否可在小程序中播放
- */
- export const isPlayableInMiniProgram = (url) => {
- const streamType = getStreamType(url)
- // 小程序只支持RTMP和HLS(m3u8)
- return streamType === 'rtmp' || streamType === 'hls'
- }
- /**
- * 构建适用于不同平台的流地址
- * @param {String} originalUrl 原始流地址
- * @param {Object} options 配置选项
- * @returns {Object} 不同平台适用的流地址
- */
- export const buildPlatformStreamUrls = (originalUrl, options = {}) => {
- // 提取流的关键信息 (比如设备ID)
- const streamType = getStreamType(originalUrl)
- const { streamServer = {}, fallbackToHls = true } = options
-
- // 获取流服务器地址
- const { rtmpServer, hlsServer, wsFlvServer } = streamServer
-
- // 提取设备ID或流标识 (示例: 使用正则表达式提取)
- const streamIdMatch = originalUrl.match(/(\d+_\d+\.live\.flv)/) ||
- originalUrl.match(/([^/]+)\.m3u8/) ||
- originalUrl.match(/stream=([^&]+)/)
-
- const streamId = streamIdMatch ? streamIdMatch[1] : null
-
- if (!streamId) {
- // 如果无法提取流ID,则返回原始URL
- return {
- h5Url: originalUrl,
- miniProgramUrl: isPlayableInMiniProgram(originalUrl) ? originalUrl : null
- }
- }
-
- // 构建不同平台的URL
- const urls = {
- h5Url: originalUrl, // 默认H5使用原始URL
- miniProgramUrl: null
- }
-
- // 微信小程序优先使用RTMP和HLS
- if (rtmpServer && streamType !== 'rtmp') {
- // 构建RTMP URL (小程序支持)
- urls.miniProgramUrl = `${rtmpServer}/${streamId.replace('.live.flv', '')}`
- } else if (hlsServer && streamType !== 'hls') {
- // 构建HLS URL (小程序支持)
- urls.miniProgramUrl = `${hlsServer}/${streamId.replace('.live.flv', '.m3u8')}`
- } else if (isPlayableInMiniProgram(originalUrl)) {
- // 原URL已经是小程序可播放格式
- urls.miniProgramUrl = originalUrl
- } else if (fallbackToHls) {
- // 假设存在通用HLS地址可以使用
- const deviceId = streamId.split('_')[0] || streamId
- urls.miniProgramUrl = `${hlsServer || 'https://stream.example.com/hls'}/${deviceId}.m3u8`
- }
-
- return urls
- }
- export default {
- getStreamType,
- isPlayableInMiniProgram,
- buildPlatformStreamUrls
- }
|