acfun json 弹幕 转换 bilibili xml 弹幕
以往一直使用 acdown 自帶的 acplay 功能看 acfun 的視頻, 然而 acdown 已經停止更新, 并且 acfun 又一次改版。。。
因此想繼續用 acplay, 只能把A站的彈幕轉換為B站的格式看了。
首先, 想要轉換彈幕文件, 我們首先要下載解析出A站和B站的彈幕。 關于如何獲取彈幕, 參見https://tiansh.github.io/的ASS 項目。 具體來說, 就是提取cid, 然后下載彈幕。
我借鑒了該項目下載彈幕的程序。 分別是:
A站
// 獲取彈幕id var getVid = function (callback) {var player, m, vid = null;try {player = document.querySelector('iframe#ACFlashPlayer-re');m = player.src.match(/vid=(\d+)/);vid = Number(m[1]);} catch (e) { }if (!vid) try {player = document.querySelector('object#ACFlashPlayer-re');m = player.querySelector('param[name="flashvars"]').getAttribute('value').match(/videoId=(\d+)/);vid = Number(m[1]);} catch (e) { }if (!vid) setTimeout(function () {getVid(callback);}, 1000); else callback(vid); };// 通過彈幕id獲取彈幕內容 // 彈幕內容是A站直接提供的數據 var getDanmaku = function (vid, callback) {GM_xmlhttpRequest({'method': 'GET',// FIXME 最后可能需要個彈幕上限,不過就先這樣吧'url': 'http://static.comment.acfun.mm111.net/' + vid,'onload': function (resp) {var data;try {data = JSON.parse(resp.responseText);data = data.reduce(function (x, y) { return x.concat(y); });} catch (e) { data = null; }if (!data || typeof data.length !== 'number') callback(vid);else callback(vid, data);},'onerror': function () {callback(getVid);},}); };// 將彈幕內容轉換為程序內部的表達方式 var mina = function (vid, danmaku) {danmaku = danmaku.map(function (line) {var info = line.c.split(','), text = line.m;return {'text': text,'time': Number(info[0]),'color': RRGGBB(Number(info[1])),'mode': [undefined, 'R2L', undefined, undefined, 'BOTTOM', 'TOP'][Number(info[2])],'size': Number(info[3]),'bottom': false,// 'sender': String(info[4]),// 'create': new Date(Number(info[5]) * 1000),};});var name;try { name = document.querySelector('#txt-title-view').textContent; }catch (e) { name = '' + vid; }var ass = generateASS(setPosition(danmaku), {'title': document.title,'ori': location.href,});startDownload('\ufeff' + ass, name + '.ass'); };B站: /** bilibili*/// 獲取xml var fetchXML = function (cid, callback) {GM_xmlhttpRequest({'method': 'GET','url': 'http://comment.bilibili.com/{{cid}}.xml'.replace('{{cid}}', cid),'onload': function (resp) {var data = (new DOMParser()).parseFromString(resp.responseText, 'text/xml');var danmaku = Array.apply(Array, data.querySelectorAll('d')).map(function (line) {var info = line.getAttribute('p').split(','), text = line.textContent;return {'text': text,'time': Number(info[0]),'mode': [undefined, 'R2L', 'R2L', 'R2L', 'BOTTOM', 'TOP'][Number(info[1])],'size': Number(info[2]),'color': RRGGBB(Number(info[3])),'bottom': Number(info[5]) > 0,// 'create': new Date(Number(info[4])),// 'pool': Number(info[5]),// 'sender': String(info[6]),// 'dmid': Number(info[7]),};});callback(danmaku);}}); };// 獲取當前cid var getCid = function (callback) {debug('get cid...');var cid = null, src = null;try {src = document.querySelector('#bofqi iframe').src.replace(/^.*\?/, '');cid = Number(src.match(/cid=(\d+)/)[1]);} catch (e) { }if (!cid) try {src = document.querySelector('#bofqi embed').getAttribute('flashvars');cid = Number(src.match(/cid=(\d+)/)[1]);} catch (e) { }if (!cid) try {src = document.querySelector('#bofqi object param[name="flashvars"]').getAttribute('value');cid = Number(src.match(/cid=(\d+)/)[1]);} catch (e) { }if (cid) setTimeout(callback, 0, cid);else if (src) GM_xmlhttpRequest({'method': 'GET','url': 'http://interface.bilibili.com/player?' + src,'onload': function (resp) {try { cid = Number(resp.responseText.match(/<chatid>(\d+)<\/chatid>/)[1]); }catch (e) { }setTimeout(callback, 0, cid || undefined);},'onerror': function () { setTimeout(callback, 0); }}); else {setTimeout(getCid, 100, callback);} };
在此向原作者致敬!
接下來, 我們下載了acun和bilibili的json和xml格式, 那么簡單, 就是轉換文件而已。 在此我用了 python 做 json轉換。
代碼本身很簡單:
import sys reload(sys) sys.setdefaultencoding('utf-8')file = open('C:\\Users\\Administrator\\Desktop\\ab\\2.json')try:content = file.read() finally:file.close()import jsonjcon = json.loads(content, encoding='GB2312')f2 = open('C:\\Users\\Administrator\\Desktop\\ab\\2.xml', 'w') f2.write('<?xml version="1.0" encoding="UTF-8"?>\n') f2.write('<i><chatserver>chat.bilibili.com</chatserver><chatid>3978802</chatid><mission>0</mission><maxlimit>1000</maxlimit><source>k-v</source>')jcs = jcon[0] for jc in jcs:a = jc['m']b = jc['c']# c: time, color, mode, size, sender, create, ?c = b.split(',')f2.write('<d p="')# timestr = '%s,' % (c[0])f2.write(str)# modestr = '%s,' % (c[2])f2.write(str)# sizestr = '%s,' % (c[3])f2.write(str)# colorstr = '%s,' % (c[1])f2.write(str)# createstr = '%s,' % (c[5])f2.write(str)# poolf2.write('0,')# senderstr = '%s,' % (c[4])f2.write(str)# dmidstr = '%s">' % (c[6])f2.write(str)# textstr = '%s</d>\n' % (a)f2.write(str)f2.write('</i>')代碼不復雜, 但是有些問題值得記錄。 首先是python的編碼問題, 開始用json.loads()直接讀的時候老出錯, 后來才發現是編碼問題沒有處理好。 然后還有, 讀取到txt之后, 可以print, 但輸出文件的時候顯示“'ascii' codec can't encode character u'\u5657' in position 0: ordinal not in range(128)”
搜索后發現, 寫的時候也要指定編碼。
參考了一下文章: http://hjc73.blog.163.com/blog/static/1046929201364115635197/
http://python3-cookbook.readthedocs.org/zh_CN/latest/c06/p02_read-write_json_data.html
over, enjoy it!
總結
以上是生活随笔為你收集整理的acfun json 弹幕 转换 bilibili xml 弹幕的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转:MediaCoder H.264格式
- 下一篇: Android 界面设计尺寸规范