npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@lucifinil/tts-editor

v1.1.8

Published

## 介绍

Downloads

244

Readme

tts-editor

介绍

  • 提供多音、文本、数值、英文、停顿等五种方式的划词选择。 1724981348142 1724981436277

多音

  • 对汉字的处理,不同的汉字有多种读音或音调,可对该字指定读法。

文本

  • 提供人名、地址、车牌号、标点符号、ID、日期、时间、计量单位等,指定该文本按照什么形式读。

数值

  • 提供读数值、读数字、读手机等。

英文

  • 提供读字母和读单词。

停顿

  • 在某处可停顿 0.5s、1s、2s 等

Install

  npm i @lucifinil/tts-editor

Usages

<template>
  <div>
    <tts-editor
      :ref="`ssml${index}`"
      :text="show_list[index].value"
      :richText="show_list[index].richText"
      @ssmlGenerated="ssmlGenerated($event, index)"
      @playAudio="playAudio($event, index)"
      @input="changeInput($event, index)"
    >
      <template #btn>
        <a-button type="primary" size="small">生成素材</a-button>
      </template>
    </tts-editor>
  </div>
</template>

<script>
import TtsEditor from '@lucifinil/tts-editor'
export default {
  name: 'tts',
  components: {
    TtsEditor
  },
  data() {
    return {
      text: '新鲜的微风666吹动我的衣袂,如同爱人的鼻息吹着我的手一样。',
      show_list: []
    }
  },
  methods: {
    ssmlGenerated(ssml, index) {
      this.show_list[index] = {
        ...this.show_list[index],
        ssml
      }
      this.ssmlList[index] = ssml
    },
    changeInput(value, index) {
      this.show_list[index] = {
        ...this.show_list[index],
        value
      }
      const domRef = this.$refs[`ssml${index}`][0]?.$el
      const targetElement = domRef?.querySelector('.tts-editor-content')
      this.show_list[index].richText = this.htmlSerializer(targetElement)
    },
    htmlSerializer(targetElement) {
      if (!targetElement) return
      const contentChildren = Array.from(targetElement?.childNodes)
      const clone = document.createElement('div')
      contentChildren.forEach(child => {
        clone.appendChild(child.cloneNode(true))
      })
      const serializer = new XMLSerializer()
      return serializer.serializeToString(clone)
    },
    async getAudioPath(index) {
      try {
        const {value} = this.show_list[index]
        const {data} = await this.$robot.getBroadcast({
          text: `<speak>${value}</speak>`,
          voice: 'aixia',
          volume: 50,
          speechRate: -80,
          vendor: 2,
          cloudType: 1
        })
        return `/rbc_web/rest/patter/playVideo?filePath=${data}`
      } catch (err) {
        return ''
      }
    },
    playAudio(val, index) {
      const {isSpeak, audioUrl} = val
      const domRef = this.$refs[`ssml${index}`][0]?.$el
      const audioElement = domRef?.querySelector('#ssml-audio')
      if (!audioElement.paused) {
        audioElement.pause()
        return
      }
      if (audioUrl && !isSpeak) {
        this.$nextTick(() => audioElement.play())
        return
      }
      this.getAudioPath(index).then(audioUrl => {
        if (!audioUrl) {
          this.$message.error('播放失败')
          return
        }
        this.$refs[`ssml${index}`][0].audioUrl = audioUrl
        this.$nextTick(() => audioElement.play())
      })
    }
  }
}
</script>

可单独使用,也和独立使用,以上为多个编辑器同时使用。使用时注意确保 ref 唯一。

props

  • text 文本内容。多行请用\n分割。
  • richText htmlString 用于编辑时回显。

event

  • input 失去焦点时获取当前编辑框输入的内容。
  • playAudio 将文字转为语音 试听。
  • ssmlGenerated。生成 ssml 代码。
<s>
  新
  <phoneme alphabet="py" ph="xian1">
    鲜
  </phoneme>
  的微风
  <say-as interpret-as="cardinal">
    666
  </say-as>
  吹动我的
  <say-as interpret-as="name"> 衣袂 </say-as>,
  <say-as interpret-as="address">
    如同
  </say-as>
  爱人的鼻息吹着我
  <phoneme alphabet="py" ph="di2">
    的
  </phoneme>
  手一样
  <say-as interpret-as="punctuation">
    。
  </say-as>
  <say-as interpret-as="date">
    2024-07-25
  </say-as>
  <say-as interpret-as="time">
    12:00:00
  </say-as>
</s>

注意事项

  1. html 标签入库时要去除外层无用的标签
extractInnermostContent(htmlString) {
      const tempDiv = document.createElement('div');
      tempDiv.innerHTML = htmlString;
      function getInnermostDiv(element) {
        let currentElement = element;
        while (currentElement.children.length === 1 && currentElement.firstElementChild.tagName.toLowerCase() === 'div') {
          currentElement = currentElement.firstElementChild;
        }
        return currentElement;
      }
      const outerDiv = tempDiv.firstElementChild;
      if (outerDiv && outerDiv.tagName.toLowerCase() === 'div') {
        const innermostDiv = getInnermostDiv(outerDiv);
        if (innermostDiv !== outerDiv) {
          outerDiv.innerHTML = innermostDiv.innerHTML;
        }
        return outerDiv.outerHTML;
      }
      return htmlString;
    }
  1. html 转字符转
htmlSerializer(targetElement) {
    if (!targetElement) return;
      const contentChildren = Array.from(targetElement?.childNodes);
      const clone = document.createElement('div');
      contentChildren.forEach(child => {
        clone.appendChild(child.cloneNode(true));
      });
      const serializer = new XMLSerializer();
      return serializer.serializeToString(clone);
    },
  1. html 字符转反序列化
 parserDomHtml(htmlString) {
      const parser = new DOMParser();
      const doc = parser.parseFromString(htmlString, 'text/html');
      return doc.body.firstChild;
    },

License

MIT