/** * 媒体工具类 - 处理视频流地址转换 */ // 流协议类型 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 }