Smpak
首先感谢taotao(学苑ID:jintaohu)童鞋和m4gic童鞋的辛勤付出,没有你们两位的研究,iphone版的语音功能不可能这么快实现。 要实现iphone版SuperMemo的语音功能,首先要解决的是如何制作出一体式的smpak文件,这一工作,舍得称其为"打包",就是把当前课程的所有内容都放到一个smpak文件里,只有这样,音频文件才有可能被iphone版的SuperMemo读取. 光有smpak包还不够.你还需要修改SuperMemo的数据库文件(smm.dat),当你通过iphone从SuperMemo官网把课程下载完毕时,程序会做一个导入的工作.很显然我们自制的smpak无法享受这一待遇了,那就需要进行手工修改smm.dat文件. 首先做好smm.dat的备份,以免操作失误.用ifuxbox之类的工具将smm.dat从iphone中复制出来,然后开始用SQLiteExpert对数据库进行修改.事实上,我们只要改两个表的数据就行.下面是基本的步骤: 第一个表叫COURSES,顾名思义就是用来储存课程基本信息的.这个表修改的重点是往里边写入guid号(相当于课程的身份证号,可以在course.xml文件里找到)、课程名称,同时记下CourseId这个数值,以便下一步使用; 第二个表叫ITEMS,这是用来储存课程内容的.当前课程有几个item文件,就得往里写几条记录.修改的重点有以下几条: Id:手工编一个,通常取当前表最大数加1即可; CourseId:上一步得到的数据,这是跟COURSES表关联的重要数据; Number:填item文件的编码即可,如item00289.xml,那就填"289"; Name:参看course.xml中相应item的name值. Question和Answer:重中之重,需要将Item文件中的Question段和Answer段分别写入.比如下面这个文件: <?xml version="1.0" encoding="utf-8"?> <item xmlns="http://www.supermemo.net/2006/smux"> <lesson-title>Cambridge English Grammar in Use</lesson-title> <chapter-title>Have got and Have</chapter-title> <question-title>选择正确的答案(多选题)</question-title> <question>Evan and Jane had a farm in Wales, ______ they? Are they still there?<br/><checkbox display="inline"><option correct="true">didn’t</option><option>weren’t</option><option>hadn’t</option></checkbox><br/></question> <answer></answer> <answer-audio>true</answer-audio> <modified>2011-09-12</modified> <template-id>10005</template-id> <gfx-1 id="5" [...]
舍得所知道的最早研究并揭开SMPAK神秘面纱的是m4gic童鞋,当时他画了几张图,一一讲解了smpak文件中的奥秘,现在舍得根据自己的实践,用文字来阐述一下,可让更多的人迅速熟悉其中的规律,为实现smpak文件的自由制作创造机会。 一、头部 依先后顺序: 8字节:-SMArch- 2字节:版本号,01 01 2字节:锁定标识,01 00 4字节:EntrChnk的偏移值 4字节:NameChnk的偏移值 8字节:DataChnk的标志 以上共计28字节. 严格地讲,DataChnk标志不应归入头部,因为每个数据区块都有此标志. 二、数据区DataChnk 每组数据(一个页面文件或媒体文件)占一个数据区块,每个区块前均有DataChnk标志(DataChnk标志占8字节)。 三、文件列表区EntrChnk 此区相当于SMPAK里的索引,记录了文件名和文件内容的位置和长度等信息。 标志占8个字节,后面紧跟着的文件总数,占4个字节。然后是每个文件的相关信息,其格式如下(以第1条为例): 名称偏移值1:NameChnk offset1 (4字节) 长度1(2字节) 压缩标记1:(flags,2字节,表示内容是否压缩) 数据区偏移值1:DataChnk offset1 (4字节) 数据库尺寸1(相当于长度):DataChnk size1(4字节) 总共一个文件信息占16字节,依此循环.因为有文件总数这个参数,有多少个文件,只要用一个循环,就可以把上述的各项信息一一读取出来.由名称偏移值1可得到文件名位置,加上长度1可返回文件名;通过察看压缩标记1,可判断是否要调用压缩程序;由数据区偏移值1可得到文件内容储存位置,加上尺寸可返回文件内容. 四、文件名储存区NameChnk NameChnk标志占8字节 随后是NameChnk区的总长度,8字节,后面还有2个字节,作用不详.在这2字节后边,就是文件名列表(注意和文件列表区分开来). 如果是解包操作的话,只消将EntrChnk里的数据取出,然后分别取文件名和文件内容,写入文件就OK了.其实打包的操作正好与此相反,先把各个数据计算好,然后分别将三个区的DataChnk、EntrChnk和NameChnk加上文件头写入文件即可。遗憾的是python处理二进制文件读写颇有不便之处,不然的话,打包应该是比较容易实现的. 本文版权归舍得英语魔法学苑所有,欢迎转载,转载请注明作者和出处。谢谢! 作者:舍得 首发:舍得@学习力博客

近期评论