shawind 发表于 2009-1-4 17:27:09

简单的转换ie7缓存的dat文件到wma文件

以前在XP下用ie6,可以直接从缓存中找到网页上播放的wma文件。而最近换了win2008系统,ie7+wmp11的环境下,会给在线播放的wma文件加一定的保护。具体的流程是,把wma文件添加一定量的dump字节后,更名为dat文件缓存。于是弄了个小工具解决这个问题。编译后,与缓存好的dat文件放于同一目录,运行即可。

import std.stdio:writefln,writef,readln;
import std.file;
import std.c.stdio;

extern(C) int setlocale(int , char*);
static this()
{
    fwide(stdout,1);
    setlocale(0, "china");
}

void d2w(char[] name)
{
    byte[] dat;
    byte[] wma;

    writefln("你要修改的dat文件名:" ~ name);
//读入wma
    dat = cast(byte[])read(name);
    writef("原dat文件的大小为:" );
    writefln( dat.length );

    wma = dat;
    writef("改wma文件的大小为:" );
    writefln( wma.length );
//新文件名
    char[] wma_name = name ~ ".wma";

    write(wma_name, wma);

}

//停住命令行
void pause()
{
    writefln("按任意键退出...");
    char[] t;
    readln(stdin, t);
}

//判断是不是dat后缀
int check(char[] name)
{
   if(name.length < 5)
   {
        return -1;
    }
    else
    {
        if (name == ".dat")
        {
//            writefln(name);
//            writefln(name);
            return 0;
        }
        else
        {
            return -1;
        }
    }
}

//入口
void main(char[][] args)
{
    if (args.length > 2)
    {
        goto End;
    }

//获取目录列表
    char[][] mylist = listdir(getcwd());
    writef("本目录下所有文件的数量为:");
    writefln(mylist.length);

//计数器
    int dc = 0;

    foreach(int i, char[] c; mylist)
    {
        if(!check(c))
        {
  //          writef(c);
  //          writefln("是dat文件");
                d2w(c);
                dc++;
        }
        else
        {
            writef(c);
            writefln("忽略");
        }
    }

    writef("被修改的dat文件是:");
    writef(dc);
    writefln("个");

End:
     pause();
}

ravenex 发表于 2009-1-7 04:12:08

但是……转换不正确。版主自己试过能行么?我是用这个地方的asx来试的:http://lantis-net.com/zettai/001h.asx,对应的缓存文件是zettai_high.dat
上面的代码的主要逻辑就是剪掉文件开头的65536个字节然后转存到另一个文件里。请问65536是从什么地方知道的?直接在我找的那个asx缓存得到的dat文件中里找不到WMA的signature,即便是在65536这个位置看也没什么特别的地方。请问版主可以帮忙看看有没有办法转换那个dat文件吗?

我是直接用Ruby来剪掉那65536字节,测试过得到的结果跟顶楼的程序一样。
#!/usr/bin/env ruby

def dat2wma(dat_file)
if (dat_file =~ /^(.+)\\.dat$/i) && (!File.exist? "#{$1}.wma")
    content = nil
    open dat_file, 'rb' do |input|
      input.pos = 65536
      content = input.read
    end
    open "#{$1}.wma", 'wb' do |output|
      output.write content
    end
else
    0
end
end

def convert_folder(dir='.')
Dir.entries(dir).grep(/\\.dat$/i).inject 0 do |count, file|
    print "Converting #{file}..."
    wma_len = dat2wma "#{dir}/#{file}"
    puts "done, written #{wma_len} bytes."
    count + 1
end
end

if __FILE__ == $0
count = convert_folder ARGV || '.'
puts "Done converting #{count} dat file(s)."
end

另外想问一下,为什么连续的writef/writefln调用不用writefln(formatString, args)来代替?感觉清爽很多。而D里的数组切片也可以用$来指定数组末尾而不必用array.length这么麻烦的写法。然后获取文件后缀可以用std.path.getExt(),替换后缀可以用std.path.addExt(),不必自己做数组操作。

shawind 发表于 2009-1-8 14:51:53

1.65535个字节的这个,就是直接在ie的页面上用wmp11放的那种wma。
我转的是那种常见国内的dj网站上的舞曲(有个亲戚需要),同时开个N的网页后,然后把dat文件找出来转一下就行了。一次就可以搞定N首。
而那个001h.asx实际连接的文件是个asf文件,如此处理应该不行吧。

2.下那个001h.asx,可以试试用一个现成的软件叫HiDownload。这个文件,很长的,等它自己播放完,然后找缓存太麻烦了。

3. 原理一样,ruby的结果和d的结果当然也一样。

4.writefln(formatString, args), 你不说,我都想不起来用格氏化...

5.$是比较后才加入的,忘了用了...

6.path的用法,我是临时查的文档,完全不知道全部用法...

7.我码代码的习惯太恶劣了,要改变,库文档也要多读...

ravenex 发表于 2009-1-8 18:13:43

小的在XP下也是用IE7和WMP11,但是WMA缓存的时候还是普通的WMA,能直接找到
原来那个是ASF啊,那小的知道怎么做了~多谢版主大大!

小的写Ruby脚本放出来主要也是想对比下,觉着这种事情还就应该是脚本发挥作用的地方

shawind 发表于 2009-1-8 18:22:49

所以我一开始就说了,在“win2008系统,ie7+wmp11的环境下”,呵呵~

是啊,用ruby写批量下指定的东西脚本很方便的,有封装的很好的http,ole模块。

secondsen 发表于 2009-1-17 16:00:06

用ruby写批量下指定的东西脚本很方便的,有封装的很好的http,ole模块。

NND。。为什么我就没看过这些。。汗。。。那书我读得太少了

公仔迦南 发表于 2009-10-13 17:06:13

版主能不能把编译好的文件上传,我不会编译

shawind 发表于 2009-10-13 20:17:54

其实,这个程序有问题,不能100%转换出100%正确的wma文件,所以就不提供了。抱歉。
页: [1]
查看完整版本: 简单的转换ie7缓存的dat文件到wma文件