陈镕,韩亦多BRIANHAN,陈景浩,邹铭宸
这是一个趣味音视频播放器,它可以导入本地视频或录制新视频后播放。如果你对任何地方感到疑惑,程序的“帮助”页或许能帮到你。除了传统视频播放器的开始/暂停以及快进/快退功能以外,对于给定的视频,它能加载已有弹幕,也可以加入新弹幕和设定时间点字幕等,让观影过程更加有趣!
- 导入本地视频:点击主页面的导入按钮,打开设备本地相册,选取视频导入,之后可在主页面视频列表中查看和编辑。
- 录制视频:点击主页面录制按钮,调用设备相机功能,获取权限后可开始录制,录制完成后视频将自动保存到app中,可查看和编辑。
- 视频播放:点击列表视频进入播放页面,可通过进度条直接跳转和快进。
- 歌词/字幕编辑:点击视频播放器右上方图标,下方弹出编辑界面。输入时间点和歌词、字幕内容,用户可在右侧记录本查看自己写的内容,点击保存后将歌词字幕加载进视频中。之后的查阅用户便可以看到自己记录的歌词字幕,点击记录本中的内容可以跳转到对应的时间点进行查看。
- 视频弹幕:每个视频都有自己的本地弹幕,播放视频时会随着时间自动播放本地弹幕。用户也可以在编辑页面发送弹幕,弹幕会被保存在本地的app中。
- 视频信息编辑:长按主页面列表中的视频,进入视频信息编辑页面,用户可以修改视频的信息和简介并进行保存。点击右上方的加载弹幕文件,用户可以从本地导入xml弹幕文件(参考bilibili)加载视频弹幕。
- 视频列表过滤:用户在主页面搜索框输入字符,app会根据输入内容自动过滤视频列表,点击打开会播放字条内容最相符的视频。
- 文件系统存储
- UI动画制作
- 自定义UI控件
- 多媒体权限调用
- 视频加载、播放、控制技术
- Activity间互相交互
- 应用程序生命周期监听
- 动作监听
- 列表刷新技术
- Kotlin数据类
再见了,jvav
@satgo1546:还剩两周左右的时间🐶本来想整个QArt生成器啊,数字电路教学应用啊,更好用的浏览器啊,不过我在B站上看到一个让人眼前一黑的好活,我们整个安卓版也不是不行,还可以加个定时和结算假装做了个音游。
@Daniel-ChenJH:确实有意思。
@OvertheBrain:活有点太狠了。以这学期学的技术感觉做游戏有点难(?)可以沿用这个思路做一个音视频播放器。想了一个趣味音视频播放器:可以app里内置几个音乐/视频,用户可以往app里导入用特定格式编写的歌词本,软件将歌词展示成类似于视频里的样子,并将音视频根据歌词分块——就是分割歌词,像音乐软件里根据歌词播放。
@stevenzmc:这样的话我们是要根据歌词本生成不同的控件来展示歌词吗?
@satgo1546:“特定格式的歌词本”指XML layout(不是)。如果不想整活浓度过高的话就不要搞各种控件了,自定义一个歌词显示视图,自己绘制就是。
@OvertheBrain:主要layout真没啥控件可以用……原生开发有什么成熟的组件库吗?我之前开发app都是用React-Native的(
@satgo1546:确实,WinForm有现成的ListBox可以用,Android连回收视图转接器也得自己写。可能每种组件各有一些成熟的库,就用很长很长的依赖列表掩盖过去吧!
两天后
@OvertheBrain:但我在想做这么一个东西出来没啥屌用,而且学到的知识也没用几个,比如他们给我们的API不用感觉怪浪费的。还有就是可行性:每首歌的歌词都是不一样的,怎么区分,怎么播放。
@satgo1546:思考:没有屌用是否是其最大的屌用?要说的话多媒体、UI、动画,还是用得蛮足的。我个人倾向于不要用给的API……这会使有人三十年后把作业APK翻出来回忆(挖黑历史)时发现运行不了,原因是API已经没了。 关于带歌词音视频播放,ASS字幕和LRC歌词文件给出了标准解决方案:同目录下同名不同扩展名的文件即是对应歌词文件。又例如实现动画时,也可以参考ASS中的动画效果指令等。这么说来,创意性又没有了,不如还是做音游算了(x 其他两人有何想法?
@stevenzmc:搞个本地音频/视频库app?比较类似的我就想到这个。
一周后
@satgo1546:好耶,拖到只剩一周了!不管怎么样先把库建起来吧。……我都邀请了,被邀请者需要登上GitHub手动确认一下🐱 鉴于除了趣味本地音视频播放库以外没有其他想法,就做这个吧。
@Daniel-ChenJH:可以。
媒体播放器Media Player Classic的图标是写有数字“321”的场记板,而更现代的界面引向象征着下一代的“002”,故名321002。
——当然不是这样。这个数字只是从random.org随机生成的0到999999之间的随机数。
5月1日
@satgo1546:昨天花了大约四个小时整了个基础的视频播放器。(此处有两张应用截图。)明明代码才两百行。原生开发是这样的……
@OvertheBrain:提问,为啥是绿的?
@satgo1546:你取个色看十六进制值就知道了。……然后就在考虑歌词本的格式。实现歌词按时间显示出来并不困难:我已经把框架搭好了,只要在刷新进度条的时候顺便把歌词也刷新了就是。但是,因为是趣味播放器…… 另外,加载外部视频的功能也完全没做。👻 目前的视频都是直接塞在资源文件里随app编译打包的,也导致仓库克隆要花很久(
@OvertheBrain:以我现在学过的组件确实想不出怎么趣味。而且我们有学过怎么加载外部视频吗?
@satgo1546:靠,这也太合理了,确实没学过……(突然发现了课件里的一行小字:“void setVideoURI(Uri uri)
:以Uri的方式设置VideoView播放的视频源,可以是网络Uri或本地Uri”。)
@OvertheBrain:那可以用他给的那个API玩玩了。
@satgo1546:整挺好。我在(播放页右上角)弄了个可以显示一个边栏的功能,标签是“编辑”但其实里面什么都没做,你要做查看评论之类的话可以直接往里面删改,加油🐱 ……我突然发现这样是不是可以做成弹幕视频网站?怪起来了。
@OvertheBrain:确实。歌词展示要怎么整出有趣的互动形式是个问题。
两天后
@satgo1546:(此处有一张应用截图。)我做了(弹幕)绘制,内容来源还是内嵌资源。
不到一周后
老师:五一放假,大作业报告延期到下周。
12日晨
@OvertheBrain:很好,我们现在满打满算只剩两天半。我想了一下,这个项目具体可以做的功能。
(首页)这一块我加了几个功能(UI是空的,功能尚未实现):
- 打开系统视频:调用系统相机或者相册,打开内部视频,并存放到列表里
- 获取视频列表:点击按钮跳出搜索框,用字节给的API拉取视频列表,用返回的视频地址播放视频
- 帮助:文档工作
至于(播放页)这里,主要是一个音视频编辑功能和分享功能。音视频编辑主要在下面的编辑区域,计划是分成两半:一边是一个输入框,输入时间点和歌词(也可以是弹幕),输入完后另一边会出现一个控件(怎么设计看人),点击控件可以跳转到对应时间点并在视屏附上对应弹幕(弹幕可永久保存)。分享功能是通过调用字节给的短视频发布API来实现。
所以现有的任务是:
- 搜索栏的过滤功能
- 调用系统内部相机功能
- 拉取视频列表功能
- 音视频编辑功能
- 分享功能
- UI优化(如果时间允许,可以做个登录界面,固定用户的学生ID,用于API调用)
@OvertheBrain:@全体成员 醒了的话看一下任务可行不可行,可行的话挑一两个任务来认领吧,时间紧迫(
@OvertheBrain:@satgo1546 还有关于视频信息的存储,因为这个项目应该是要做持久化存储的,视频信息用List文件存的方式可能要改成课上讲的持久化存储,你可以看一下统一规定一个存储方案。
@satgo1546:我认为这任务量太恐怖了。现在只剩两天了,至少要砍掉一半。根据砍掉哪一半,我建议以下两种路线:
- 使用字节跳动给的API,所有数据全部存储在云端:免去所有持久化事项
- 不使用任何网络功能,所有数据保存在本地:免去所有网络事项
我调查了现在已经在作业本中提交项目地址的5个大作业。其中:
- 4个是单人组,1个是两人组
- 1个项目使用了字节跳动提供的API。该项目成员在一周和两周前在课程群中询问过API调用异常问题,至今没有得到任何回应
- 1个项目使用了很多个其他第三方API。该项目内容丰富,完成度极高(相对),推测该成员有过相关开发经验
- 1个项目使用了网络资源(但不是API)。虽然是抖音再世,其实只做了界面
- 2个项目没有使用任何网络资源
- 4个项目使用了SQLite数据库,其中1个项目使用了Room
字节跳动提供的API少有人用,用过的人都说坏,存在大量不稳定和不确定因素。结合作业期限,故决定将所有数据保存在本地。
删去与网络相关的功能,剩下的待实现任务如下。
- 搜索栏的过滤功能
- 调用系统相机或相册(择一),将所得视频导入到视频列表中
- 发送弹幕程度的能力
- 数据持久化:方案、显示本地视频列表、在本地保存发送的弹幕
- 帮助:文档工作
@stevenzmc:文档和展示PPT我来吧,最近忙毕设有点抽不开身。
@Daniel-ChenJH:我也一起弄帮助文档和PPT制作吧[泪奔]技术活实在干不来。
@satgo1546:草,两个人一起做PPT那也太怪了,这可是Android项目啊。你们谁选一个写app内的使用说明界面吧,这个活就是在Android Studio里拖拖拖的,不用写代码。
……
@OvertheBrain:我做1(过滤视频列表)和3(发送弹幕)吧。顺便UI这方面你觉得有啥可以优化的?比如给视频加个封面图显示之类的。可以丰富一下列表项,加个删除按钮啥的。
@satgo1546:我不知道怎么从视频里提取封面……哦Android好像有现成API。现在主页的列表因为图方便用的是ListView,缩略图加载是耗时操作,这不会很容易,如果还有时间的话再说吧(
@OvertheBrain:不用RecyclerView是因为用起来太sb了吗?
@satgo1546:是啊。这么抽象的控件有什么使用的必要吗?我在刻意避开过度设计的那些东西。比如播放页里本来有个功能是无操作3秒后把暂停按钮和进度条隐藏,因为Handler太烦了就删掉了;Menu也没有用资源,直接在Activity里手动创建。不过确实现在这个主界面看起来过于简陋了。
关于持久化方案,考虑到屑安卓对文件权限瞎几把乱限,Android的SQLite也遵从着过度设计的原则,而且总不能把几十MB的视频塞到数据库里吧……我认为持久化的好方案是直接用文件系统:在私有存储目录下查询*.xml获得视频列表,文件名是视频名,XML是弹幕文件,同名的另一个文件就是视频内容。
@OvertheBrain:我觉得可。另外我想把时间点也存起来,类似于一个保存歌词本的功能。你能想象出我在说什么吗?
@satgo1546:时间点就直接按弹幕格式存在XML里应该就可以。输入框的内容存在 <d></d>
之间,时间点存在 p=""
里。
@OvertheBrain:我是说用户自己输入的时间点,这个时间点是要显示在下面的那个UI里的。或者说你想把这么多弹幕都塞到下面去?
@satgo1546:没错。如果想要歌词和弹幕分开的话,加一个flag就是。例如,认定底部弹幕是歌词,在编辑界面里只显示底部弹幕。
@OvertheBrain:好主意。
一天后
@OvertheBrain:把filter给做好了,顺便优化了一下UI。删除功能因为目前存储没做好,所以应该是不能用的,@satgo1546 我给视频加了个description属性,你可以看着加。
又一天后
@Over the brain:@Frog Chen 你存储那边整的怎么样了,我可能需要参考一下
@Frog Chen:我还在清理代码
Adapter的水分有点多,正在消化
@Over the brain:Adapter有啥问题吗
@Frog Chen:我在找应该往哪里插入读写文件系统的代码
@Over the brain:@satgo1546 你存储那边整的怎么样了
@Frog Chen:现在基本确定了情况
通过Android Studio里的文件管理器强行导入了两个外部视频并显示出来
@Over the brain:那列表增删是调用哪几行代码
@Frog Chen:主要变动是为了使用私有目录,把PredefinedVideos的初始化时间推迟到了Application.onCreate处;当用户请求导入外部视频时,主活动将维护该列表。PlayerActivity仍按ID寻找PredefinedVideo数据对象,该对象中记载了目标视频和弹幕文件的URI,以便后续读写
@Over the brain:PredefinedVideo这个列表是存在私有目录吗
@Frog Chen:另外,没有修改VideosAdapter。当对PredefinedVideos列表进行了修改后,只需要重新调用filter方法,就能自动更新列表显示的内容
@Over the brain:PredefinedVideo这个列表是存在私有目录吗 我感觉这个是可以按词条存进sqlite里的
毕竟视频以地址方式存储
@Frog Chen:在Application.onCreate中,PredefinedVideos被私有目录中的文件初始化。当用户添加视频时,视频会被复制到私有目录中,这样下次打开app的时候自动就会从文件系统中读出视频列表
视频不按地址存储,因为考虑到用户可能会导入SD卡上的视频,而后把SD卡移除
虽然把视频统统拷到私有目录里非常不厚道,但方便[doge]
如果真的按地址存储,会遇到大量权限相关问题,而且各个Android版本上相关的权限控制不同,极为混乱。升级到Android 9后,我用过的app里,就没见有一个能正常播放从其他应用里分享出来的文件的
@Over the brain;哦,可以
@Over the brain:对了,你打开系统文件的时候有没有做调用系统相机拍视频
@Frog Chen:暂时没有
@Over the brain:我一开始预想是这两功能合一块的
@Frog Chen:应该问题不大
@Over the brain:来不及做也无所谓
@Frog Chen:直接调用系统相机应该比较方便
又又一天后
@Over the brain:现在这个妖魔鬼怪是长这个样子的
当然有个最核心的问题
我弹幕文件的持久化存储没实现,不过框架搭好了
@Frog Chen 因为我实在没搞懂你这个文件的路径和video列表的存储逻辑
@Frog Chen:我这边刚把缩略图做完
我来看看
@Over the brain:其他我都写好了,就只要把这个弹幕写进私有目录的文件里
问题在我用文件流找不到这个路径
@Frog Chen;是的 我早上搞的时候就发现URI是个很烦的东西
所以现在把URI全部灭绝了
@Over the brain:@Buster@号哭 @听心鼓点 现在收尾工作有写readme和ppt,要求见大作业pdf
你们俩各选一个可以开始做了
不过这个项目可能要到晚上才能写完,你们可以先根据现有的开始写,写不出的问我们俩就行
@听心鼓点:我写readme
@Frog Chen:因为实现难度问题()把修改视频信息放到主页去了
现在长按列表项就会跳转到修改视频信息页面
@Over the brain:是因为acitivity刷新吗
@Frog Chen:刷新,而且要跨两级(修改视频描述会刷新主界面)
@Over the brain 2022/5/14 13:50:55 @Frog Chen 对了,你那个弹幕文件读写加了吗
@Frog Chen:我正在研究
@Over the brain:是路径问题还是xml读写问题
@Frog Chen:你新增了一个Comments变量,但是所有歌词还是加载在danmaku里
@Over the brain:comments是暂存用的
就是你每加一句歌词就存在当前activity的comments里
@Frog Chen:有没有考虑过删除已有歌词的问题
@Over the brain:点保存以后就直接从comments里取时间点和歌词来组成弹幕
我没想加删除
用comments的原因是我觉得从动态生成的组件里取数据太麻烦了
就用了一个暂存过渡
@Frog Chen:点了保存之后会把暂存的歌词加到弹幕列表里?
@Over the brain:对
@Frog Chen:这个列表就纯粹展示用的?
@Over the brain:你点击可以跳转
@Frog Chen:可以
@Frog Chen:那么为什么需要一个暂存机制
直接加到列表里应该差不多
@Over the brain: 方便用户返回
反悔*
@Frog Chen:草 有道理的
@Over the brain:就你加完一堆字幕给你个机会审查一下
因为我懒得做删除了
@Frog Chen:检查发现有不对劲的地方直接删了全部重来
非常合理
笑死了
@Over the brain:删除还要从xml里面找
太难搞了
@Frog Chen:要做的话可以直接在原始列表上改,保存的时候直接整个列表全部序列化回去
不过摸了
就按暂存的做吧
@Over the brain:这个是动态生成,我不知道怎么一个个拉
而且没用list和转接器
@Frog Chen:对的
@Frog Chen 2022/5/14 14:57:52 好,弹幕持久化做完了
@Over the brain:辛苦了
我有空的话再把UI优化一下