看不了电视直播了?那就自己做一个(一)

事情的起因是这样的,前两天打开电视看直播,突然变成了下面这个画面。

开始以为是太久没更新了,想着重新安装一下就好了。结果上网一查才知道,电视直播软件都下架了。

电视直播只能安装有线,或者通过央视频手机收看了。有线暂时安装不了,用手机看又总是感觉很别扭。

虽然也可以通过投屏的方式用电视播放,但切换频道时还得使用手机操作,非常的麻烦。

广电的这波操作出发点可能是好的,后续应该会提供其他收看方式,但是目前这个真空期着实有点尴尬。思来想去,干脆自己动手做一个吧

经过一个周末的折腾,过程虽然有一点点曲折,但总算是完成了第一个电视版本,感觉和以前相比,清晰度还不错,切换也更流畅。

再来看一下卫视。

也是OK的

电视端有了,又突然想着把它放到手机上,虽然手机上可以直接使用央视频播放,但还是有点繁琐,于是又稍微做了一些调整,推出了一个手机端的版本,切换还是相当的丝滑。

最后我其实还改了一版在电脑上使用的,但是这个除了摸鱼好像也没别的用处,所以对于我来说意义不大。

实现篇

接下来说一下具体的实现,会涉及到一些编程相关的内容,如果不感兴趣可以直接跳到结尾。

客户端应用开发

这一篇先介绍客户端的应用的开发,主要就是安卓应用的开发。虽然以前没有这方面经验,但是想法有了,剩下的交给chatGpt就好了。

1. 播放器

首先是播放器的选择,一开始我采用了原生MediaPlayer,主要是考虑到跟各版本安卓系统的兼容性会好一点,而且它使用起来非常的简单,十几行代码就搞定了。

java 复制代码
public class PlayActivity extends Activity {
    ChannelService channelService;
    VideoView videoView;
 
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        channelService = new HttpChannelService();
        setContentView(R.layout.activity_play);
        videoView = findViewById(R.id.video_view);
        channelService.loadChannels((success, message) -> runOnUiThread(() -> {
            Channel channel = channelService.getDefaultChannel();
            videoView.setVideoURI(Uri.parse(channel.getSource()));
            videoView.start();
        }));
    }
}

后来替换成了谷歌开源的ExoPlayer,因为只是简单使用,所以代码基本上也没什么差别。

java 复制代码
public class PlayActivity extends Activity {
    ChannelService channelService;
    private StyledPlayerView videoView;
    private ExoPlayer player;
 
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initView();
        initChannels();
    }
 
    private void initView() {
        setContentView(R.layout.activity_play);
        videoView = findViewById(R.id.video_view);
        player = new ExoPlayer.Builder(this).build();
        videoView.setPlayer(player);
    }
 
    private void initChannels() {
        channelService = new HttpChannelService();
        channelService.loadChannels((boolean success, String message) -> runOnUiThread(() -> {
            ChannelService.Channel channel = channelService.getDefaultChannel();
            play(channel);
        }));
    }
    
    private void play(Channel channel){
        player.setMediaItem(MediaItem.fromUri(channel.getSource()));
        player.prepare();
        player.setPlayWhenReady(true);
    }
}

2. 监听器

接下来就是考虑对遥控器按键的监听处理,对于这个应用而言,只需要监控方向键以及退出键就好了,当然也可以根据需要对菜单键或者确定键进行响应。

java 复制代码
videoView.setOnKeyListener((view, keyCode, event) -> {
    switch (keyCode) {
       // 向下操作处理 切换下一个频道
       case KeyEvent.KEYCODE_DPAD_DOWN:
          if (event.getAction() == KeyEvent.ACTION_DOWN) {
              Channel channel = channelService.getNextChannel();
              play(channel);
              return true;
          }
          break;
     }
     return false;
});

3. 视频源管理

把ChannelService留到最后讲,是因为它的作用通过下面的接口定义就一目了然了。

这里之所以要定义成接口,比如常见的通过m3u获取,是因为考虑到视频源可能有不同实现,关于实现部分会在下一篇详细讲解。

java 复制代码
public interface ChannelService {
 
    /**
     * 加载频道
     */
    void loadChannels(LoadCallBack callBack);
 
    /**
     * 获取默认频道
     */
    Channel getDefaultChannel();
 
    /**
     * 获取下一个频道
     */
    Channel getNextChannel();
 
    /**
     * 获取前一个频道
     */
    Channel getPrevChannel();
 
}

4. 手机版

手机版因为没有了遥控器,所以需要对触屏动作进行监听来对视频进行操控,主要就是左右滑动的切换,以及上下滑动的音量调节等。

结语

因为是即兴的创作,也没有打算能长久使用,所以很多细节我并没有考虑,比如内容的缓存,节目回看,网络监控等等这些。但是这几天使用下来体验还是挺不错的。后续我可以把整个源码开放出来,大家有兴趣可以自行去补充。

到这里客户端的实现就讲完了,下一篇再讲一下其他部分的实现。

相关推荐
xinjia_ctrl41 分钟前
暑假实习总结
git·后端·spring·maven·intellij-idea
IT_陈寒2 小时前
Java Stream处理大集合,我的内存怎么就炸了
前端·人工智能·后端
悟空码字2 小时前
四轮对话两张配图:用 WorkBuddy 优化公众号发文配图的实战指南
人工智能·后端·腾讯
ServBay2 小时前
xAI的 Grok Bot发布,AI 已经学会自己上班了
后端·ai编程·grok
分支预测失败2 小时前
RISC-V 多核缓存一致性机制解析:MESI 协议族、CMO 扩展与 Linux 同步原语
后端
n8n3 小时前
Spring AI 检索增强生成(RAG)实战:让模型掌握你的私有知识
后端
Nturmoils3 小时前
只备份一个 schema,别把整库都搬走
后端
妙码生花3 小时前
利用AI从零学Go并完成实战项目,完工总结:目录结构
前端·后端·go
妙码生花3 小时前
利用AI从零学Go并完成实战项目,完工总结:商业级开源产品定位和核心特性介绍
前端·后端·go
程序员cxuan3 小时前
GPT-6 Astra 的提示词泄露了,里面居然藏着个保安?
人工智能·后端·程序员