instrumental 发表于 2021-3-12 17:53:08

制作FastWordQuery可以使用的语音库

本帖最后由 instrumental 于 2021-3-18 04:18 编辑

FastWordQuery

在为[]制作单词卡片的时候,发音一直是一个比较头痛的问题。
有道的发音是比较容易获取的,但是有道的发音不纯正,很多音读得不是非常正确。
TTS也不能与真人发音相比,而且机器合成音在背单词的时候会有不良影响。
相对来讲朗文词典的真人发音就非常的纯正。
所以FastWQ特别针对朗文mdx词典制作对应的字典查询服务,以便快速的为单词添加读音并下载音频到本地。
按照以下步骤,可以很方便的为整个单词本快速的添加音频。

使用的时候切记不要导入词典而是直接去设置py

特制的朗文 6 本地词典

1b5de81464fb46ca892eab4a698a207e#1b5de81464fb46ca892eab4a698a207e#1206#/LDOCE6双解 修改 可提取音频/entry.js
f24817ae7bc736d4365908da3f87f77f#efd11ff3580a0f7dc0735119d296cf98#1297932816#/LDOCE6双解 修改 可提取音频/L6mp3.mdd
ee13707d1b966a49bc3149b111cd6b4d#60a7f4d9a40eb2359b4ece19876f584d#26550272#/LDOCE6双解 修改 可提取音频/L6mp3.mdd.db
7f301751b90d10f33412de45a599f2da#60a24ed264dc49dd7a8b05a1ace848cf#124057083#/LDOCE6双解 修改 可提取音频/L6mp3.mdx
aefbf1c0cae35980122ace73f533409e#df04641926e6d88694ecee7dcada3d19#11501568#/LDOCE6双解 修改 可提取音频/L6mp3.mdx.db
e79f484789815550da723c944b8f27d8#e79f484789815550da723c944b8f27d8#12642#/LDOCE6双解 修改 可提取音频/LDOCE6.css

修改程序的YHCD,然后用正则表达式制卡就好了

https://i.loli.net/2021/03/12/GWjiQILVaP2yUE5.png

- (https://github.com/sth2018/FastWordQuery)
- [为单词添加真人发音(朗文 mdx 词典)](https://sth2018.github.io/FastWordQuery/docs/get_mdx_ldoce6_sounds.html)
- (https://www.yuque.com/purequant/anki/sudl9z)


















#-*- coding:utf-8 -*-
import os
import re
import random
from ..base import *

VOICE_PATTERN = r'<a href="sound://([\w/]+\w*\.mp3)"><img src="img/spkr_%s.png"></a>'
VOICE_PATTERN_WQ = r'<span class="%s"><a href="sound://([\w/]+\w*\.mp3)">(.*?)</span %s>'
MAPPINGS = [
    ['br', ],
    ['us', ]
]
LANG_TO_REGEXPS = {lang: regexps for lang, regexps in MAPPINGS}
DICT_PATH ='D:\\111111111111111111111111111111.mdx.mdx'


@register()
class xxxxx(MdxService):

    def __init__(self):
      dict_path = DICT_PATH
      # if DICT_PATH is a path, stop auto detect
      if not dict_path:
            from ...service import service_manager, service_pool
            for clazz in service_manager.mdx_services:
                service = service_pool.get(clazz.__unique__)
                title = service.builder._title if service and service.support else u''
                service_pool.put(service)
                if title.startswith(u'LDOCE6'):
                  dict_path = service.dict_path
                  break
      super(xxxxx, self).__init__(dict_path)

    @property
    def title(self):
      return getattr(self, '__register_label__', self.unique)

    @export('PHON')
    def fld_phonetic(self):
      html = self.get_html()
      m = re.search(r'<span class="pron">(.*?)</span>', html)
      if m:
            return m.groups()
      return ''

    def _fld_voice(self, html, voice):
      """获取发音字段"""
      for regexp in LANG_TO_REGEXPS:
            match = regexp.search(html)
            if match:
                val = '/' + match.group(1)
                name = get_hex_name('mdx-'+self.unique.lower(), val, 'mp3')
                name = self.save_file(val, name)
                if name:
                  return self.get_anki_label(name, 'audio')
      return ''

    @export('BRE_PRON')
    def fld_voicebre(self):
      return self._fld_voice(self.get_html(), 'br')

    @export('AME_PRON')
    def fld_voiceame(self):
      return self._fld_voice(self.get_html(), 'us')

    def _fld_image(self, img):
      val = '/' + img
      # file extension isn't always jpg
      file_extension = os.path.splitext(img).strip().lower()
      name = get_hex_name('mdx-'+self.unique.lower(), val, file_extension)
      name = self.save_file(val, name)
      if name:
            return self.get_anki_label(name, 'img')
      return ''

    @export('IMAGE')
    def fld_image(self):
      html = self.get_html()
      m = re.search(r'<span class="imgholder"><img src="(.*?)".*?></span>', html)
      if m:
            return self._fld_image(m.groups())
      return ''

    @export('EXAMPLE')
    def fld_sentence(self):
      return self._range_sentence()

    def _fld_audio(self, audio):
      name = get_hex_name('mdx-'+self.unique.lower(), audio, 'mp3')
      name = self.save_file(audio, name)
      if name:
            return self.get_anki_label(name, 'audio')
      return ''

    @export()
    def fld_sentence_audio(self):
      return self._range_sentence_audio()

    @export('DEF')
    def fld_definate(self):
      m = m = re.findall(r'<span class="def"\s*.*>\s*.*<\/span>', self.get_html())
      if m:
            soup = parse_html(m)
            el_list = soup.findAll('span', {'class':'def'})
            if el_list:
                maps = [u''.join(str(content) for content in element.contents)
                                    for element in el_list]
            my_str = ''
            for i_str in maps:
                my_str = my_str + '<li>' + i_str + '</li>'
            return self._css(my_str)
      return ''

    @export()
    def fld_random_sentence(self):
      return self._range_sentence()

    @export()
    def fld_first2_sentence(self):
      return self._range_sentence()
   
    @export()
    def fld_random_sentence_audio(self):
      return self._range_sentence_audio()

    @export()
    def fld_first2_sentence_audio(self):
      return self._range_sentence_audio()

    def _range_sentence(self, range_arr=None):
      m = re.findall(r'<span class="example"\s*.*>\s*.*<\/span>', self.get_html())
      if m:
            soup = parse_html(m)
            el_list = soup.findAll('span', {'class':'example'})
            if el_list:
                maps = [u''.join(str(content) for content in element.contents)
                                    for element in el_list]
            my_str = ''
            range_arr = range_arr if range_arr else
            for i, i_str in enumerate(maps):
                if i in range_arr:
                  i_str = re.sub(r'<a[^>]+?href=\"sound\:.*\.mp3\".*</a>', '', i_str).strip()
                  my_str = my_str + '<li>' + i_str + '</li>'
            return self._css(my_str)
      return ''

    def _range_sentence_audio(self, range_arr=None):
      m = re.findall(r'<span class="example"\s*.*>\s*.*<\/span>', self.get_html())
      if m:
            soup = parse_html(m)
            el_list = soup.findAll('span', {'class':'example'})
            if el_list:
                maps = []
                for element in el_list:
                  i_str = ''
                  for content in element.contents:
                        i_str = i_str + str(content)
                  sound = re.search(r'<a[^>]+?href=\"sound\:\/(.*?\.mp3)\".*</a>', i_str)
                  if sound:
                        maps.append()
            my_str = ''
            range_arr = range_arr if range_arr else
            for i, e in enumerate(maps):
                if i in range_arr:
                  i_str = e
                  sound = e
                  mp3 = self._fld_audio(sound.groups())
                  i_str = re.sub(r'<a[^>]+?href=\"sound\:.*\.mp3\".*</a>', '', i_str).strip()
                  my_str = my_str + '<li>' + i_str + ' ' + mp3 + '</li>'
            return self._css(my_str)
      return ''

    @export()
    def fld_extra_examples(self):
      lst = re.findall(r'href="/(@examples_.*?)\">.*?<', self.get_html())
      if lst:
            str_content = u''
            for m in lst:
                content = self.builder.mdx_lookup(m)
                if len(content) > 0:
                  for c in content:
                        str_content += c.replace("\r\n","").replace("entry:/","")
            return self._css(str_content)
      return ''   

    @with_styles(cssfile='_ldoce6.css')
    def _css(self, val):
      return val
   


^([^\t]*)\t(.*)
\1\n<link type="text/css" rel="stylesheet" href="LDOCE6.css"/><div id="LDOCE6_Zzz_1"><span class="entry" id="zzz" new="NewInLdoce"><span class="entryhead"><span class="hwd"></span><span class="hyphenation"></span> <span class="brevoice"><a href="sound://\2"></span brevoice><img src="img/spkr_r.png"></a> <span class="amevoice"><a href="sound://\2"></span amevoice><img src="img/spkr_b.png"></a><span class="buttons"></span></span><span class="sense" id="zzz_s1"> <span class="def"></span def></span></span></div><script src="entry.js"></script>\n</>


有点复杂就说下原理,懂的人自然懂

FastWordQuery的作者特别做了朗文 6的支持,包含 .py 文件 特制的 mdx mdd

我就根据那个特制的MDX直接造了新的mdx出来,然后就支持了.
py代码比较复杂看不懂,我只是改了里面的词典名 xxxxxxx

然后正则表达式是用来制作mdx的

词头\tMP3


想想应该也没几个人用得上,学英语以外的外语的人应该不多



herozyg 发表于 2021-3-12 19:21:57

Thanks a lot.

VimVim 发表于 2021-3-18 08:28:07

给力!感谢分享!

frand 发表于 2021-3-18 14:24:12

FastWordQuery不是本身就支持朗文6的发音和命名查询么?我下载了朗文6的词典文件就可以直接用了。

torresgoal 发表于 2021-8-7 06:11:23

这个真不错啊,还有图片呢?

tudou365 发表于 2021-8-20 17:14:24

下来看看吧,

宁冷越 发表于 2024-7-30 01:47:36

我就属于看不懂的那个
页: [1]
查看完整版本: 制作FastWordQuery可以使用的语音库