[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[问题求助] 求同时精通Python和powershell的大神,把Py代码转成Ps

本帖最后由 5i365 于 2022-1-17 13:18 编辑

酷狗的歌词是专用的KRC格式的, 想把它转成LRC格式的, 在Github上找到了python版的工具,
很不错, 正在使用, 但是要装python, 即使打包成exe也不小, 看了下py代码, 只有七八十行, 实际处理字符串的代码也不多,
求同时精通Python和powershell的大神,把Py代码转成Ps, 非常感谢
下面有歌词解析代码的 python, java, c 语言版, 供参考


github地址:
https://github.com/veficos/krc2lrc

Python代码
  1. # coding=utf-8
  2. # author=veficos
  3. import codecs
  4. import zlib
  5. import re
  6. import os
  7. from tkinter import *
  8. from tkinter import ttk
  9. from tkinter.filedialog import askopenfilename, askdirectory
  10. def decompress_krc(krcbytes):
  11.     key = bytearray([ 0x0040, 0x0047, 0x0061, 0x0077, 0x005e, 0x0032, 0x0074, 0x0047, 0x0051, 0x0036, 0x0031, 0x002d, 0x00ce, 0x00d2, 0x006e, 0x0069])
  12.     decompress_bytes = []
  13.     i = 0
  14.     for ch in krcbytes[4:]:
  15.         decompress_bytes.append(ch ^ key[i % 16])
  16.         i = i + 1
  17.     decode_bytes = zlib.decompress(bytearray(decompress_bytes)).decode('utf-8-sig')
  18.     decode_bytes = re.sub(r'<[^>]*>', '', decode_bytes)
  19.     for match in re.finditer(r'\[(\d*),\d*\]', decode_bytes):
  20.         ms = int(match.group(1))
  21.         time = '[%.2d:%.2d.%.2d]' % ((ms % (1000 * 60 * 60)) / (1000 * 60), (ms % (1000 * 60)) / 1000, (ms % (1000 * 60)) % 100)
  22.         decode_bytes = decode_bytes.replace(match.group(0), time)
  23.     return decode_bytes
  24. def krc2lrc(file, saveto):
  25.     with codecs.open(file, 'rb') as f:
  26.         decode_bytes = decompress_krc(bytearray(f.read()))
  27.         fp = codecs.open(saveto, "w", 'utf-8')
  28.         fp.write(decode_bytes)
  29.         fp.close()
  30. root = Tk()
  31. savedir = ''
  32. def select_files_command():
  33.     names = askopenfilename(filetypes =(("Kugou Krc File", "*.krc"), ("All Files", "*.*")),
  34.                             title = "Choose a krc file.", multiple=True)
  35.    
  36.     try:
  37.         for file in names:
  38.             saveto = os.path.join(savedir, os.path.basename(file).replace('.krc', '.lrc') if savedir else file.replace('.krc', '.lrc'))
  39.             krc2lrc(file, saveto)
  40.             label = ttk.Label(root, text ="%s转换成功" % os.path.basename(file))
  41.             label.pack(side=BOTTOM)
  42.     except Exception as e:
  43.         label = ttk.Label(root, text ="转换失败: %s" % str(e))
  44.         label.pack(side=BOTTOM)
  45. def select_savedir_command():
  46.     global savedir
  47.    
  48.     name = askdirectory()
  49.     savedir = os.path.join(savedir, name)
  50.    
  51. Title = root.title("krc2lrc小工具")
  52. menu = Menu(root)
  53. root.config(menu=menu)
  54. file = Menu(menu)
  55. file.add_command(label = 'Open', command = select_files_command)
  56. file.add_command(label = 'SaveTo', command = select_savedir_command)
  57. menu.add_cascade(label = 'File', menu = file)
  58. menu.add_cascade(label = 'Exit', command = lambda:exit())
  59. root.mainloop()
复制代码

本帖最后由 idwma 于 2022-1-20 20:54 编辑

回复 24# 5i365
  1. sc -enc utf8 $($krc -replace '\.krc$', '4.lcr') $(foreach ($match in ($decode_bytes -split '\r\n') -replace '^.*\[.*\]\s*$|\[.*?,.*\]')
  2. {
  3. if ($match -notmatch '^\s*$') { $match }
  4. })
复制代码

TOP

本帖最后由 5i365 于 2022-1-20 18:15 编辑

回复 23# idwma


    大侠, 请教两个问题:
code3的效果是这样的:
[id:0356EC8B]

[ar:胡歌]

[ti:逍遥叹]

[by:]

[hash:1415e6eab8e8b0538f5fb66526c9eb65]

[al:]

[sign:]

[qq:]

[total:313547]

[offset:0]

[language:eyJjb250ZW50IjpbXSwidmVyc2lvbiI6MX0=]

[00:00.10]胡歌 - 逍遥叹

[00:00.70]作词:陈宇任
------------------------------------------------------------
code4的效果是这样的:
[00:00.10]胡歌 - 逍遥叹

[00:00.70]作词:陈宇任

[00:00.89]作曲:陈宇任

Code4删除了code3中没用的信息, 现在想来个更简单点的, 把所有的 [XXX:XXX] 的内容全删除[即:方括号中有个英文的:], 只留下歌词,顺便把空行也删除掉, 怎样修改这部分代码?
-----------------------------------------------------------
code3:
  1. sc -enc utf8 $($krc -replace '\.krc$', '3.lcr') $(foreach ($match in $decode_bytes -split '\n')
  2. {
  3. if ($match -match '\[(\d*),\d*\]') { '[{0:mm:ss.ff}]{1}' -f [datetime]([int64]$matches[1] * 10000), ($match -replace '^\[\d*,\d*\]') }
  4. else { $match }
  5. })
复制代码
-----------------------------------------------------------
code4:
  1. sc -enc utf8 $($krc -replace '\.krc$', '4.lcr') $(foreach ($match in ($decode_bytes -split '\n') -replace '^.*\[.*\]\s*$')
  2. {
  3. if ($match -match '\[(\d*),\d*\]') { '[{0:mm:ss.ff}]{1}' -f [datetime]([int64]$matches[1] * 10000), ($match -replace '^\[\d*,\d*\]') }
  4. elseif ($match -ne '') { $match }
  5. })
复制代码

TOP

回复 22# 5i365


    可以吧我也是抄的
https://gist.github.com/marcgeld/bfacfd8d70b34fdf1db0022508b02aca

TOP

回复 21# idwma


$gzipStream.Close()
$out.Close()
这两行不加好像也能执行, 不加有什么副作用吗?

TOP

本帖最后由 idwma 于 2022-1-18 15:58 编辑

回复 23# 5i365
  1. $krc='test.krc'
  2. $krcbytes = gc $krc -enc byte
  3. $key = @(0x0040, 0x0047, 0x0061, 0x0077, 0x005e, 0x0032, 0x0074, 0x0047, 0x0051, 0x0036, 0x0031, 0x002d, 0x00ce, 0x00d2, 0x006e, 0x0069)
  4. [byte[]]$decompress_bytes = foreach($ch in $krcbytes[4..$krcbytes.count]){$ch -bxor $key[$i++ % 16]}
  5. $in = New-Object System.IO.MemoryStream( , $decompress_bytes )
  6. $in.Position=2
  7. $gzipStream = New-Object System.IO.Compression.DeflateStream $in, ([IO.Compression.CompressionMode]::Decompress)
  8. $buf = New-Object 'byte[]' 1024
  9. [System.IO.MemoryStream] $out = New-Object System.IO.MemoryStream
  10. while ($($len = $gzipStream.Read($buf,0,$buf.length);$len) -gt 0){$out.Write($buf, 0, $len)}
  11. $gzipStream.Close()
  12. $out.Close()
  13. $tmp = $out.ToArray()
  14. $decode_bytes=[Text.Encoding]::utf8.GetString($tmp[0..$tmp.count]) -replace '<[^>]*>'
  15. sc -enc utf8 $($krc -replace '\.krc$','.lcr') $(foreach($match in ($decode_bytes -split '\n') -replace '^.*\[.*\]\s*$'){if($match -match '\[(\d*),\d*\]'){'[{0:mm:ss.ff}]{1}' -f [datetime]([int64]$matches[1]*10000),($match -replace '^\[\d*,\d*\]')}elseif($match -ne ''){$match}})
复制代码
1

评分人数

TOP

回复 22# idwma


    用替换的方法稳吗? 有点担心会过滤掉歌词内容

TOP

回复 19# idwma


    还有就是一行之后会有一个空行, zlib的行与行之间没有空行

TOP

回复 19# idwma


    歌词全了, 但是前面比zlib的会多出来下面的:
-----------------------------------------------
[id0356EC8B]

[ar:胡歌]

[ti:逍遥叹]

[by:]

[hash:1415e6eab8e8b0538f5fb66526c9eb65]

[al:]

[sign:]

[qq:]

[total:313547]

[offset:0]

[language:eyJjb250ZW50IjpbXSwidmVyc2lvbiI6MX0=]

TOP

回复 17# idwma

感谢, 能解出来一半,到2.11的时点就没有了 另外, 输出有点乱, 下面是两个输出文件的比较
    https://wss1.cn/f/7e3y8i4p7ze 复制链接到浏览器打开

TOP

回复 15# went


    感谢大侠指点, 想了一下, 综合考虑, 决定使用您的那个coder, 原因有如下几点

有时我需要处理的歌词文本文件很多, 编码也不统一, 用上面的ps代码, 发现循环处理的效率没有 coder 快

目前酷狗歌词解码和powershell判断文本编码的脚本, 都通过诸位高手解决了, 但是CMD代码中包含PS代码, 还要加dll还要判断文本编码, 感觉用你的coder全可以搞定, 也不用判断编码, 直接用那个自动参数就行了, 药到病除

现在有两个请求:
1.大侠能告知一下, 怎样把上面的C代码, 加到您的coder代码中, 也就是添加上解码酷狗歌词的功能,
2.大侠能否给coder.exe加上一个覆盖参数, 如-y ,直接把文本内存中操作, 然后覆盖原来的文件, 这样就可以不用重命名了

这样, 我只用一个coder.exe+cmd代码就可以了, 成功率和效率都要高
无论如何都非常感谢!

TOP

回复 14# 5i365


    真想把coder.exe放到ps里,用base64存放
    但coder.exe还是有16kb,我觉得大可不必

TOP

回复 13# went


    要是能把这个功能加到您的 那个coder编码工具里就好了, 以后想用coder了, 上次自己试了下, 还是没有能力把它集成到PS代码中, 集成进去后, 就不用带coder.exe了

想把coder集成到ps代码的最后位置

TOP

回复 10# 5i365


    c是用的zlib的静态库,不需要额外的dll,powershell不行
  1. #include "zlib/zconf.h"
  2. #include "zlib/zlib.h"
复制代码

TOP

回复 11# went


    感谢分享, 实在看不懂,

要是不用dll就能搞定就好了

TOP

返回列表