Vim也是个播放器

昨天清理Google Reader未读,看到这篇文章,类似的效果我看过Word,Excel版,不过用记事本是第一次看到,有点意思,当然记事本没有宏功能,它的翻页功能肯定使用其它程序控制的。

连Windows那个简陋的记事本也能放动画了,作为“编辑器之神”的Vim不可能不行吧,于是我蛋疼起来就折腾一下,做了个Vim版,猛击这个链接来看视频。

MPlayer来播放

其实把电影当成字符来播放根本就不是什么新玩意,mplayer早就有这个功能

mplayer -vo aa -monitorpixelaspect 0.5 filename

因为aa输出驱动不能保持正确比例(mplayer的“-aspect”参数),改用“-monitorpixelaspect 0.5”后比例比较正常。它也有一些快捷键

  • 1、2键为控制对比度
  • 3、4键控制亮度
  • 5键切换快速渲染
  • 6键切换抖动方式
  • 7键反转效果
  • a键则是切换回mplayer控制方式

把“aa”换成“caca”就是彩色输出。不过Ubuntu 9.10自带的mplayer没有把这个“aa”视频输出驱动编译进去,medibuntu的版本就有,搞错,应该是smlplayer作者编译的版本。用ubuntu-tweak添加个第三方源更新下mplayer就行,最版版本中名为“Mplayer”的源好像又被移除了,手动添加ppa源页面

mplayer使用的是aa-project项目的aalib库(在Ubuntu名字改成“libaa”),看看更新历史,1998年3月10日第一版,最后更新2001年4月25日,这东西是非常非常古老的,那个年代的hacker玩ascii-art真是想多变态就能玩多变态。这玩意是Linuxer装逼必备的,各位装逼犯们,有兴趣想知道怎么做继续看下去。

注意:下面的写的都是在Linux下完成的,只用到mplayer、aview和一些linux命令,windows用户需要自找代替工具,但原理是一样的。额外使用的工具、代码和最终结果文本可以猛击这里下载。

更新:留言中的jiazhoulvke同学写了个shell脚本,自动完成下文的一系列操作,使用简单,不想理解原理来折腾的可以下载来看看,里面有使用说明。

Vim来播放

mplayer的播放原理不难理解,mplayer解码视频,把每一帧传给libaa来生成ascii文本,再把ascii文本转换成图像传给X显示出来。现在不用mplayer转换图像来播放了,把libaa转换过后的ascii文本弄出来,用Vim来播放。

可是想通过mplayer把这些字符提取出来没那么简单,因为它没有提供直接输出文本的选项,所以得换个思路,如下

  1. 先用mplayer来把视频的每一帧保存为图像,mplayer支持png和jpg输出,经过测试,png不压缩体积巨大,压缩速度又慢,反正这里的视频本来就是黑白的,不用那么高要求,jpg就够了,体积也很理想。
  2. 然后再用其它工具来把图像转换ascii文本,这里找到一个,是LDCN介绍过aview,通过manpage,发现也是用libaa库,连选项都是跟mplayer的一样。
  3. 再把转换后的文本合并为一个。
  4. 用Vim来打开合并后文件,编写脚本实现自动翻页。
  1. 准备工作

  2. 先建立一个空的临时文件夹,把flv文件复制进去,源视频用flashgot从这个页面抓下来的,用smplayer看一下flv的信息

    • 文件名:“bad_apple.flv”
    • 大小:6m
    • 分辨率:448×336
    • 帧速:15fps

    文件不算大,还是黑白的,更方便转成ascii了。接下来的都是终端操作了,先建立几个工作目录。

    mkdir jpg pgm txt
  3. 提取图像

  4. 执行下面的命令,所有帧都会输出为jpg放到“jpg”目录下

    cd jpg
    mplayer -vo jpeg ../bad_apple.flv

    转换也很快,不过最好不要打开文件管理器来看啊哈,几千文件在里面。转换后3283个文件共20.6 MB。

  5. 转换为pgm

  6. 把图像转换为ascii文本的工具是aview,就在“aview”这个包里,在安装(这时还不需要安装)后用asciiview来查看图像。

    为什么不是用“aview”呢?那是因为aview只支持pnm、pgm、pbm、ppm的格式,对于常见的png和jpg不支持,怎么办呢?转换一下咯,所以就有了asciiview这个脚本,它的作用就是先把图像转换成pgm格式再调用aview来显示。它用的是imagemagick的convert命令,但这里不用asciiview了,直接自己先转换好了。继续在“jpg”目录下执行

    for i in *.jpg; do convert -colorspace gray $i ../pgm/${i%.jpg}.pgm; done

    经过漫长的等待后,在“pgm”目录出现一堆pgm文件了,图像变成灰阶图形,体积增大至471.3MB。

  7. 转换成ascii

  8. 这时候就能把pgm转换成ascii文本了,郁闷的是aview不支持直接在命令行直接输出结果,我翻遍它的文档都找不到相应的选项,所以如果你想保存结果,得用aview打开,按“s”键,然后答几个问题,如保存高宽度啊,字体啊,文件名啊这些问题。娘啊,我可是有3千多个要转换啊,手动保存得何年何月啊?

    下面两个方法选一个

    旧方法:修改aview源码重新编译
    这里省略千字的折腾过程,最后我是下载源码来修改aview来实现这个功能的,改过的aview命名为“aview-mod”。用aview-mod来把pgm转换为txt,执行下面命令

    cd ../pgm
    for i in *.pgm; do aview-mod -driver stdout -contrast 32 $i | sed '$d' > ../txt/${i%.pgm}.txt; done

    新方法:脚本处理,推荐
    其实aview也支持命令行输出,只不过用法比较诡异,而不是直接输出单张结果,而是一个空白页和2张ascii页面,所以要配合再sed处理一下,截取其中一张

    cd ../pgm
    for i in *.pgm; do echo q | aview -driver stdout -kbddriver stdin -contrast 32 $i | sed -n '27,+24p' > ../txt/${i%.pgm}.txt; done

    那堆txt齐刷刷地放到“txt”文件夹下,一共6.3 MB。

  9. 合并文本

  10. 无难度

    cd ../txt
    cat *.txt > ../bad_apple.txt
  11. Vim翻页脚本

  12. 需要写一个脚本来实现自动翻页,在Vim的丰富文档帮助下,不用研究多久就写出来了。每隔67毫秒向下移动25行,因为1000ms/15fps=67,一共有3283个txt。脚本名为“ascii_player.vim”。

    function! AsciiPlayer()
        set nowrap
        set scrolloff=0
        set columns=80        
        set lines=26           
        normal gg
        let i = 1
        while i < 3283
            execute "normal 25\<CR>zt"
            redraw
            let i = i + 1
            sleep 67m
        endwhile
    endfunction
    command! AsciiPlayer call AsciiPlayer()
  13. 运行脚本

  14. 用vim打开“bad_apple.txt”,执行两条ex命令

    :source ascii_player.vim
    :AsciiPlayer

    就可以欣赏了,哇哈哈哈,一种无法抵挡装逼感油然而生。

一些补充

  • 当然你也可以用gvim来看,可惜刷新太慢,像放幻灯片。而在终端下vim翻页可是嗖嗖的,非常流畅。
  • 其实也不一定用vim来看,也可以是其它程序,只要它能实现定时自动翻页,刷新够流畅就可以。
  • 这里用的是终端默认大小,即80×25,当然也可以更大,但你的硬盘也得够大,libaa也有不少参数可选。
  • 这里用的例子视频默认是黑白的,如果是彩色的,有个东西叫二值化,GIMP有这个功能,把彩色图像换成失真度较低的黑白图像是个体力活。
该文章发布在 经验技巧,标签:, , , 。收藏该永久链接

有 20 条《Vim也是个播放器》的回复

  1. lzlh 说到:

    都是高人啊

    回复回复
  2. sareil 说到:

    有没搬到 avfun 上???

    回复回复
  3. 希锐亚 说到:

    好玩,但意义似乎不大。vim还是干它编辑器的本行就很好。现在觉得唯一可以包裹其它软件工作的只有浏览器。

    回复回复
  4. muzuiget 说到:

    @sareil
    没有

    @希锐亚
    就是无聊玩玩而已。

    回复回复
  5. yunt 说到:

    convert到aview-mod直接用管道不是更好?
    … convert -colorspace gray $i pgm:- | aview-mod -driver stdout -contrast 32 …

    回复回复
  6. muzuiget 说到:

    @yunt
    aview不支持从标准输入读取图像数据。

    回复回复
  7. 说到:

    bad apple! 大好 …

    回复回复
  8. linfan 说到:

    想象力相当惊人!

    回复回复
  9. ABitNo 说到:

    这年头什么牛人都有。。。

    回复回复
  10. jiazhoulvke 说到:

    我用的也是medibuntu的源,为啥没有aa和caca驱动呢?
    试过下载源码自己编译,没通过。

    回复回复
  11. muzuiget 说到:

    我看了下,抱歉,不是medibuntu源,是smplayer作者的源,文章已更新。源码中aa视频驱动默认禁用的,具体参数名字忘了,大概是“–enable-aa-driver”,用“./configure –help”查看吧。

    回复回复
  12. jiazhoulvke 说到:

    添加了那个源,但还是没有aa和caca驱动,看来是RP问题了……

    其实aview是可以直接输出到txt的,比如:
    echo q|aview -driver stdout -kbddriver stdin test.pgm

    这个帖子里面有介绍 http://goo.gl/lGqq

    回复回复
  13. muzuiget 说到:

    确定升级了mplayer?我用的版本为
    MPlayer SVN-r29643-Ubuntu-RVM (C) 2000-2009 MPlayer Team

    我囧,原来有人比我先做了,方法居然也差不多。其实这个命令用法我也发现了,它输出了一个空白页和两个ascii页,很郁闷,所以得处理一下,提取出其中一页,结果我先去改源代码了,改不成才写脚本,结果改成功了。

    他那里用的管道配合head和tail来搞定,确实简单多了,我还以为得很复杂,不过我刚才又想到用
    sed -n ’25,49p’
    来截取25-49行

    我迟点在重新验证一下更新文章,谢谢你的回复。

    回复回复
  14. jiazhoulvke 说到:

    我在更新完源后就已经马上升级了,还是那样,囧。

    我尝试着写一个shell脚本来完全自动化完成这一系列工作:生成图片,转换格式,生成txt,再调用vim播放。但在写vim脚本时遇到问题。你在vim脚本里用的是:
    while i < 3283
    它是专门针对badapple这个视频而言的,对于其它长度的视频来说不适用。我可以通过shell得到txt文件的总数:ls -l ~/*.txt | grep "^-" | wc -l。但不知如何把它读入vim的变量里面。查过vim的帮助文档,也google过,找不到解决方法,唯一接近的答案是r!,但用r!只能将结果读入文本中,而不是vim变量。

    回复回复
  15. muzuiget 说到:

    我记得ubuntu默认把mplayer的核心分成一个“mplayer-nogui“包的,而smplayer作者的为“mplayer”,你验证一下
    dpkg-query -S `which mplayer`
    把输出结果里包删掉,然后重新安装“mplayer”这个包,如果下载地址是ppa的话就没错了。

    那么不要读入vim里,把vim脚本也用shell script输出,比如
    txtnum=$(ls *.txt | wc -l)
    echo “while i < $txtnum"
    或者直接修改vim脚本
    sed -i 's/3283/'$txtnum'/' ascii_player.vim

    回复回复

  16. jiazhoulvke 说到:

    我用dpkg-query -S `which mplayer`的结果是:
    dpkg:没有找到 /usr/local/bin/mplayer。

    昨天另外想了个办法,终于解决了这个问题:
    normal G
    let n = line(“.”)/25
    while i < n

    endwhile

    将你的代码稍加修改,做成了个vim播放器,不知介意否?XD.
    https://dl.dropbox.com/u/3007379/soft/vimplayer.7z

    回复回复
  17. muzuiget 说到:

    那看来你的mplayer并非通过包管理软件来安装的。

    我下载试用了,很好很强大,果然自动完成,哈哈。当然不介意啦,GPL嘛,你的代码还值得我学习。

    回复回复
  18. jiazhoulvke 说到:

    囧,我是用sudo apt-get install mplayer安装的啊。不管它了,反正影响不大,能看视频就行了。

    貌似你对Nexuiz颇有研究哦?能不能教教俺怎么过2.5.2版的单人模式第12关?之前一直玩的是2.5.1版,那里面的12关很好过。前天刚下了2.5.2版,这次里面多了那把火枪,简直太变态了,被电脑烧得惨不忍睹,我又不会用那把枪,每次倒数1、2名。==”

    有什么作弊码之类的也行。XD

    回复回复
  19. muzuiget 说到:

    Nexuiz好久没玩了,新版也没装过。很久之前翻译过一些控制台命令,里面有个“bot_nofire”命令不知道还管不管用。

    回复回复
  20. 老白 说到:

    好玩。。。。。。。

    回复回复

发表评论

您的电子邮箱不会被公开。 标记为 * 的区域必须填写

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

评论须知
  • 如果有人@你的用户名,系统会发送邮件通知你。
  • 请不要在评论正文处里留下邮箱,以防被垃圾机器人采集。
  • 有问题请留在相关话题的文章上,我都会看到的。