ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

苹果CMS默认模板新建卫视直播页面实操:直播源采集与m3u8播放

苹果CMS默认模板新建卫视直播页面实操:直播源采集与m3u8播放 做苹果CMS站的兄弟应该都被问过类似的话“能不能在站里加一个直播页面把央视、各大卫视放上去点进去直接能看”我一开始也把它当成一个简单的页面需求来处理结果真正动手才发现这里面的坑比想象中多数据从哪里来、怎样让频道列表自动更新、默认模板的页面机制怎么用、播放器怎么选每一步都有讲究。这篇文章我按自己实际操作的路径把“用苹果CMS默认模板新建一个卫视直播页面”这件事从头到尾捋一遍代码和步骤都会给出来照着做就能跑起来。1. 先搞清楚你要做哪种直播页1.1 三种常见需求形态在动手之前我建议你先想清楚一个问题客户或你自己要的“直播页面”到底属于下面哪一种。第一种是纯静态展示页。页面上只有一堆电视台名字和logo点击之后调起外部的播放器去播m3u8地址页面本身不依赖苹果CMS任何数据逻辑把HTML代码放在模板目录里用后台的页面管理功能挂出来就行。这种最简单但频道列表是写死的以后改频道、换线路都要手动改文件。第二种是半动态页。苹果CMS只负责输出页面框架和导航直播频道列表通过JS去请求一个外部的数据接口比如别人维护的直播源JSON、m3u8列表前端渲染出来。好处是直播源可以单独维护换源不用改模板坏处是依赖第三方接口的稳定性和合规性。第三种是全入库型也是很多所谓的“苹果CMS采集站”在用的方式。你在苹果CMS后台新建一个“卫视直播”分类然后通过资源库采集功能把直播频道当作普通的视频数据采到本地数据库里分类和管理都走苹果CMS原生机制。页面上直接用模板标签把数据库里的直播频道循环输出每个频道对应一条m3u8播放地址。这样最“苹果CMS”更新频道也最方便加一个采集计划任务就能自动维护。1.2 卫视直播数据从哪来说到直播源这里我得先给兄弟们打个底卫视直播的视频流地址本质上就是一条m3u8链接格式类似http://某个流媒体服务器地址/xxx/live.m3u8。大部分直播源的地址都是固定的但能不能长期稳定访问、有没有授权需要你自己把控。我见过不少人直接把某个第三方“直播源”仓库的接口地址写到页面里结果没跑两周就失效了最后还是要回到自己维护源、自己做采集入库这条路。所以我的建议是如果你只是做个演示站不想折腾可以先用公开测试接口或者自己手上已有的源把页面跑通如果是正式项目最好是把数据采集到自己库里方便随时替换失效的源也方便做权限控制和播放统计。1.3 苹果CMS采集站在这里能干什么苹果CMS做采集站很多人的认知停留在“电影、电视剧、综艺”这些资源上但其实直播源同样可以通过资源库采集来维护。原理不复杂苹果CMS后台上传了一个资源库接口地址系统定时去这个地址拉取数据解析后写入本地数据库。对于直播来说第三方资源站一般会按“国内卫视”“港澳台”“央视”等分类给你接口你采集的时候把对方分类映射到本地分类之后频道列表就自动跑到自己站里了。这样做的优势很明显第一直播源更新不用手动改模板采集任务自动拉新第二你页面上输出的其实就是苹果CMS的列表页逻辑模板哪怕换成默认模板只要分类和标签匹配直播页照样能渲染出来第三如果采集到的源失效你只需要在后台把对应数据删除或下架前端页面就恢复正常了。这也是为什么我强烈建议不要把直播源写死在HTML里。2. 读懂默认模板的页面生成逻辑2.1 找到当前使用的那套模板苹果CMS的术语里“模板”就是一套控制前台页面长相的文件夹。你用的是什么模板决定了你后面所有文件往哪里放。最常见的默认模板根据版本不同可能是mxpro、macwf、default之类的名字老一点的版本可能还会有pink、blue这种以颜色命名的模板。你打开苹果CMS后台进入“系统 - 模板参数配置”里面有一个“当前模板方案”的选项能直接看到当前PC端在用的是哪个目录。确认好之后去服务器上找到网站的根目录一般情况下模板文件路径是/application/...不对准确说是/template/模板名/html/。我习惯先把整个模板目录下载到本地用VS Code打开后面改起来方便。需要特别注意苹果CMS的模板目录通常分为PC端模板和移动端模板两套分别对应html和m如果是独立移动模板目录。本文讲的都是PC端也就是html目录下的文件。2.2 模板目录里每个文件是干嘛的拿一套典型的默认模板来说html目录下会有下面这些关键文件index.html首页模板定义了整站首页怎么排版。vodtype.html视频分类列表页模板就是点某个分类后展示该分类下所有视频的页面。voddetail.html视频详情页模板展示视频简介、播放地址列表等。vodplay.html播放器页面模板点“播放”之后进去的页面。artlist.html/artdetail.html文章分类列表和文章详情模板一般做资讯用。public/存放公共区块文件的目录典型的有header.html和footer.html全站的导航栏、版权信息都在这里。gbook.html、label.html等其他杂项页面模板。知道了每个文件的作用你就明白“新建一个直播页面”其实并不是非得新建一堆东西核心是新建一个页面模板文件并让它能被访问到。苹果CMS本身对页面模板的文件命名没有强制限制你新建一个叫zhibo.html的文件后台绑定好它就能作为独立页面被访问。2.3 自定义页面是怎么被访问的苹果CMS的后台有一个“页面”功能入口在“后台 - 页面 - 页面管理”里。你可以在这里新增一个页面页面信息里有“页码”或者叫“别名”、页面标题、模板文件等字段。保存之后系统会为这个页面生成一个固定的访问链接默认访问路径类似/index.php/page/zhibo.html如果你开启了伪静态访问路径就是/page/zhibo.html。这个机制和我们平时理解的那种“在详情页里套视频分类逻辑”不太一样。它更像是一个“白纸页面”你可以指定这个页面用哪个模板文件来渲染模板里你想写什么就写什么可以直接写HTML也可以使用苹果CMS的模板标签和PHP代码去调用数据库数据。我见过不少人卡在这一步原因是后台页面管理里新建页面时“模板文件”的下拉框是空的。这时候不要慌这个下拉框读取的是当前模板目录下某些特定格式的模板文件列表如果你新建的模板文件名没有被系统识别它就不会出现在下拉框里。解决办法有两个一是手动在“模板文件”输入框里直接填zhibo.html这样的相对路径二是先建好模板文件并且模板文件里必须有苹果CMS能识别的头信息后面第3章我会讲怎么写。具体能不能识别不同版本有差异最稳妥的办法是直接改一个现成的模板文件复制改名然后再去后台绑定。3. 实操用默认模板新建卫视直播页3.1 建一个直播分类并配置采集如果你打算走“全入库型”的路线第一步就是先去后台建分类。进入“分类管理”添加一个根分类分类名称填“卫视直播”分类类型选择“视频”然后给这个分类设置一个别名比如zhibo。这个别名很重要后面采集映射和模板标签都要用到分类ID或别名。分类建好之后去“采集 - 资源库”添加一个采集接口。这里以常见的通用资源库接口为例接口地址形如http://提供方的域名/api.php/provide/vod/at/xml/。你把接口地址填进去点“获取分类”系统会列出对方网站的分类列表。你需要做的是把对方分类里的“卫视直播”“央视”等对应到你本地刚建好的“卫视直播”分类上。采集方式上我推荐使用“按分类采集”只采集直播分类不要整库全采否则会把对方网站的电影电视剧全部拉到你的直播分类里页面列表就会变得不伦不类。采集时间可以设置成每6小时或者每天执行一次直播源失效的概率不高太频繁反而会对服务器造成没必要的压力。3.2 做一个可以被后台绑定的模板文件不管走不走采集模板文件都是绕不开的。我先给出一份可以直接用的完整直播页模板源码基于默认模板的风格写成你把它保存为zhibo.html放到/template/当前模板名/html/目录下。!DOCTYPE html html head meta charsetutf-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title卫视直播 - {maccms:name}/title link relstylesheet href{$maccms.path_tpl}css/index.css style body { background: #f5f6f8; } .wrap { width: 1200px; margin: 0 auto; padding: 20px; overflow: hidden; } .channel-box { float: left; width: 280px; background: #fff; border-radius: 6px; padding: 15px; } .channel-box h3 { font-size: 16px; margin: 0 0 10px; border-left: 3px solid #e74c3c; padding-left: 8px; } .channel-list { list-style: none; padding: 0; margin: 0; max-height: 520px; overflow-y: auto; } .channel-list li { padding: 8px 10px; cursor: pointer; border-radius: 4px; margin-bottom: 4px; font-size: 14px; } .channel-list li:hover { background: #fef0ef; color: #e74c3c; } .player-box { float: right; width: 880px; background: #000; border-radius: 6px; padding: 10px; height: 520px; } .player-box video { width: 100%; height: 100%; background: #000; } /style /head body {maccms:include filepublic/header.html} div classwrap div classchannel-box h3频道列表/h3 ul classchannel-list idchannelList {maccms:vod num100 type卫视直播 orderasc bytime} li>lia href{:mac_url(page/zhibo)} title卫视直播卫视直播/a/li这里用{:mac_url(page/zhibo)}生成地址是最稳妥的它会根据你的URL模式自动判断要不要带index.php等前缀。如果你没有开启伪静态它自动生成带index.php的地址开了伪静态就生成干净的地址。比你在导航里写死/page/zhibo.html要靠谱很多。如果你用的是比较老的模板导航也可能是写死的一组a标签这种情况直接改成你自己的链接就行。改完导航清理一下浏览器缓存再刷新页面导航栏上就能看到“卫视直播”的入口了。3.5 用标签输出卫视频道列表刚才模板里用的是{maccms:vod}标签我再展开讲讲这个标签的几个参数因为不少新手栽在这里。{maccms:vod num100 type卫视直播 orderasc bytime}这里面num最多输出多少条数据。卫视直播的频道数量一般几十个给100足够但如果你的采集源里还包含了高清线路、备用线路那一个“频道”可能有好几条线路数据量可能翻倍建议改成num500。type指定分类这里填分类的名称“卫视直播”即可。如果模板里直接填分类名总是不生效那就填分类ID比如type5具体ID去后台分类管理里看。order和by排序方式。orderasc配合bytime表示按入库时间正序排列基本能保证采集的频道顺序和素材站保持一致。如果你想让顺序可控可以在后台给分类里的“影片”手动设置排序值同时把标签里的排序字段调整成对应的字段。需要注意的是{$vo.vod_play_url}这个变量拿的是默认播放地址组里的第一个地址。如果采集源返回的是多条播放线路格式是线路1$地址1#线路2$地址2这种以#分隔的格式直接输出会导致播放器拿到一长串无效字符。遇到这种情况我一般会在采集的接口配置里只让系统保留一条播放组或者在模板里用PHP对vod_play_url做一次截断取第一个播放地址具体做法我会在第4章的代码里给出。4. 播放器选型和播放逻辑实现4.1 m3u8播放为什么不能直接用video标签很多人第一次接触直播页面时都习惯直接写一个video srcxxx.m3u8然后发现浏览器要么黑屏、要么直接不播。原因是m3u8是HLS协议的视频流它不是单个视频文件而是一个“播放清单”浏览器原生虽然支持HLS但只有SafariiOS和macOS上的Safari支持得最好Windows上的Chrome、Edge、Firefox默认都不支持直接播放m3u8直播流。所以我们需要借助JS解析器把m3u8流转换成浏览器能播放的格式然后再喂给video标签。目前两个主流方案一个是hls.js单纯解决“让浏览器能播m3u8”的问题另一个是ckplayer或者DPlayer这类集成播放器它们在UI交互上做得更完整支持进度条、清晰度切换、弹幕等功能。如果你只是做卫视直播列表我觉得hls.js就够了简单直接不引入太多重量级依赖。ckplayer虽然好看但它本身也依赖hls.js解析HLS流等于多套了一层壳如果页面上只需要“点击频道 - 播放直播流”hls.js是性价比最高的选择。4.2 hls.js播放器接入方法接着上面的模板讲。hls.js接入直播的核心逻辑是实例化一个Hls对象调用loadSource加载m3u8地址然后通过attachMedia挂载到页面的video元素上。监听MANIFEST_PARSED事件等流清单解析完成后再调用video.play()如果直接不等这个事件就播放很多浏览器会报NotAllowedError因为自动播放策略不允许没有用户交互的播放。我前面给的那份模板代码已经处理了两种兼容情况支持Hls.isSupported()的浏览器Chrome、Edge、Firefox等走hls.js。原生支持HLS的浏览器Safari走video.canPlayType(application/vnd.apple.mpegurl)分支直接给video标签的src赋值。这里有个细节要注意hls.js在实例化的时候如果直播流地址里带了Token认证参数很可能因为Token过期导致播放失败这时需要在loadSource之前给Hls实例设置xhrSetup在请求里带上必要的请求头。这也是我在实际项目中踩过比较多的坑点之一尤其是一些需要防盗链的卫视源不带Referer或Cookie直接拿不到数据。var hls new Hls({ xhrSetup: function (xhr, url) { xhr.withCredentials true; xhr.setRequestHeader(Referer, http://你的网站域名/); xhr.setRequestHeader(User-Agent, Mozilla/5.0); } });如果你拿到的源对Referer校验很严格前端改请求头是不够的因为浏览器跨域请求在很多情况下会被CORS策略拦死。这时候更稳妥的方案是走服务端代理也就是让你站点的后端去请求m3u8流再转发给前端播放器但这就涉及流媒体转发的专业领域了现阶段大部分建站需求用不到我先不展开。4.3 状态切换与频道记忆页面能做到“点击频道就换台”其实不难难的是换台过程中的体验优化。我做完第一版后发现在直播流卡顿或者源已经失效的情况下点击另一个频道会出现“上一个请求还没结束下一个请求又来了”的并发问题轻则播放器卡住重则浏览器直接崩溃。解决办法是在每次切换频道之前先销毁当前正在播放的直播流再加载新的。hls.js里对应的操作是调用hls.destroy()var currentHls null; function setChannel(url) { if (currentHls) { currentHls.destroy(); currentHls null; } if (Hls.isSupported()) { var hls new Hls(); currentHls hls; hls.loadSource(url); hls.attachMedia(video); hls.on(Hls.Events.MANIFEST_PARSED, function () { video.play(); }); } }还有一个体验优化点给当前正在播放的频道加一个高亮状态。前面模板代码里已经写了点击事件里清空所有li的背景色再给当前点击的li设置背景色。如果你想要更专业一点可以加一个“当前播放”的角标或者红色小圆点代码逻辑是一样的。至于频道记忆指的是用户刷新页面后自动恢复到上一次看的频道。这个可以用localStorage实现把上一次点击的频道名和m3u8地址存到本地页面加载时取出并播放。不过这个属于加分项本文先不展开等直播页面能稳定跑起来之后再考虑这些体验上的优化就好。5. 踩坑记录与问题排查5.1 页面404和模板不生效做苹果CMS的兄弟一定遇到过这种情况明明后台页面管理里添加了页面访问却是404。我排查过几次发现原因主要集中在三个方面。第一是伪静态规则没配置好。如果你使用的是Nginx环境苹果CMS默认需要重写规则才能访问类似/page/zhibo.html这种地址规则缺失或者写错就会404。最简单的排查方法是直接访问带index.php的原始地址如果能打开说明是伪静态问题需要去检查Nginx的rewrite配置。第二是模板文件路径填错。后台“页面管理”里的“模板文件”字段填写的应该是相对于当前模板html目录的文件名。如果你把路径填成了/template/xxx/html/zhibo.html这种绝对路径系统反而找不到文件改成zhibo.html就好了。第三是模板文件没有可识别的标记。有些版本的苹果CMS只有模板文件里包含特定格式的注释或者maccms标签时后台下拉框才能识别出来。这时手动填写模板文件名并保存通常就能绕过这个问题。5.2 m3u8跨域和防盗链直播播放页最常见的问题就是播放器能加载出来但一直黑屏转圈。排除网络问题后十有八九是跨域或者防盗链。跨域问题可以在浏览器开发者工具的控制台看到CORS报错。这是因为你的页面和m3u8流地址不在同一个域名下。前面我说过可以通过xhrSetup带Referer去尝试但跨域限制严格时前端很难绕过需要服务端做反向代理。防盗链问题则分两种情况一种是源站检查Referer只要Referer不是它允许的域名就拒绝请求另一种是播放地址本身带了一个有时效的TokenToken过期后无法继续播放。前者可以在服务端通过代理转发时伪装Referer解决后者只能定期重新采集播放地址。所以采集任务设置成定时执行是很有必要的不能采一次就撂挑子不干了。5.3 采集不到直播数据如果你发现直播页面里列表是空的先去后台的“采集日志”看有没有采集成功记录。采集失败一般有两种原因一是资源库接口本身变了对方改了接口地址或参数二是你配置采集的时候没有正确映射直播分类导致数据采到了默认分类里而你的页面模板读的是“卫视直播”分类。还有个容易忽略的细节苹果CMS采集回来的数据如果vod_play_url里含有多个播放地址模板里用{$vo.vod_play_url}直接输出会得到一长串播放器播放不了。所以在模板输出前先做一次格式清洗用PHP截取第一个播放地址更稳妥。示例代码{php} $playUrl $vo[vod_play_url]; $playUrl explode(#, $playUrl); $playUrl explode($, $playUrl[0]); $playUrl trim($playUrl[1] ?? $playUrl[0]); {/php} video idplayer src{$playUrl} controls/video这段逻辑简单说就是苹果CMS多线路播放地址的格式是线路名$地址#线路名$地址先用#切出第一条线路再用$切出地址部分最后得到纯净的m3u8链接。不过模板里用{php}标签执行PHP代码不同版本对PHP标签的支持略有差异如果你在用V10版本一般没问题。5.4 导航高亮丢失点击导航栏“卫视直播”进入页面后导航栏其他菜单项都有高亮唯独这个新加的菜单不高亮。原因是苹果CMS默认模板判断导航高亮通常是判断当前页面对应的控制器或模块名称。page控制器的页面不在默认的vod、art等判断范围里所以不会自动高亮。解决办法是在header.html里加一个单独判断li {if condition$param[ctl]page}classactive{/if} a href{:mac_url(page/zhibo)}卫视直播/a /li如果你是直接在导航的循环列表里追加链接就单独写一行用$param[ctl]判断当前是否是page控制器。这样进入直播页时这个菜单就会正确高亮。这个细节不处理也不影响使用但对用户体验和整站的专业感还是有点影响的。5.5 采集站模式下直播源顺序乱跳采集入库的方式有个小问题每次采集更新可能会把频道的排序打乱导致用户每次看到频道列表的顺序都不一样。我建议在后台“分类管理”里把“卫视直播”分类设为自定义排序然后每种频道的排序值手动设置好数字小的排前面。采集任务跑完之后数据本身的排序值不会被覆盖这样列表顺序就能保持稳定。6. 最后再分享一点运维小经验做直播页面这件事我自己前后踩了很多次坑之后最大的体会是千万不要把直播页面当成一个一次性的静态页面来做。就算你今天只是临时加一个页面也建议把数据的读取逻辑走后台分类模板标签而不是在HTML里写死一堆频道链接。因为直播源这个行业更新太频繁了写死的页面看着简单一旦源失效改起来比重新做个页面还痛苦。另外一个建议是直播页上线前一定提前把播放失败的兜底逻辑想好。比如加载超时、播放报错给用户一个明显提示而不是让用户对着黑屏发呆。我在模板里习惯加一个ERROR事件监听播放器触发错误时弹窗提示“当前频道暂时无法播放请切换其他频道”体验会好很多。最后提醒一句做直播源采集和播放数据源版权和授权问题一定要心里有数。个人学习测试没问题如果用于商业站点务必确认你用的源是否合法合规这个锅甩不掉。这套方案本身不复杂关键是把“页面模板”和“数据维护”两条路想清楚。等你把直播页面跑稳了后面还可以继续扩展给频道加分组、做直播预告、接入播放统计等等都是在这个基础上延伸的。你按这篇文章的顺序走一遍应该很快就能看到自己的卫视直播页面完整跑起来。
返回列表