Голосовое воспроизведение переводчика Google. Странное

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
VBChild
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 29.10.2022 (Сб) 23:20

Голосовое воспроизведение переводчика Google. Странное

Сообщение VBChild » 29.10.2022 (Сб) 23:28

Приветствую! Нашёл в сети код воспроизведения текста, сервисом Google Translate.
Сам перевод мне не нужен, мне нужно только произношение передаваемого текста.
Загуглил свежую рабочую ссылку на TTS и оно заработало.

Но вот странная проблема. Русский текст она превращает во что-то невообразимое, при чтении. Вот пример. Послушайте сами.
При том, когда русские слова пишешь латиницей, она их читает по-русски, это хорошо слышно.

Для примера послушайте чтение на английском и немецком. Там ни каких проблем нет.

Код: Выделить всё
Option Explicit

Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long
Private Declare Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" (ByVal pCaller As Long, ByVal szURL As String, ByVal szFileName As String, ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long

Public Function GoogleSpeak(ByVal sText As String, Optional ByVal Language As String = "ru", Optional ByVal bDoevents As Boolean) As Boolean
    On Error Resume Next
    Dim sTempPath As String, ml As String
    Dim FileLength As Long

    sText = Replace(sText, vbCrLf, " ")

    If Len(sText) > 100 Then Exit Function

    sTempPath = Environ("Temp") & "\TempMP3.MP3"
   
     If URLDownloadToFile(0&, "https://translate.google.com.vn/translate_tts?q=" & sText & "&tl=" & Language & "&client=tw-ob", sTempPath, 0&, 0&) = 0 Then
        If mciSendString("open " & Chr$(34) & sTempPath & Chr$(34) & " type MpegVideo" & " alias myfile", 0&, 0&, 0&) = 0 Then

            ml = String(30, 0)
            Call mciSendString("status myfile length ", ml, 30, 0&)
            FileLength = Val(ml)
           
            If FileLength Then
                If mciSendString("play myFile", 0&, 0&, 0&) = 0 Then
                    Do While mciSendString("status myfile position ", ml, 30, 0&) = 0
                        If Val(ml) = FileLength Then GoogleSpeak = True: Exit Do
                        If bDoevents Then DoEvents
                    Loop
                End If
            End If
            Call mciSendString("close myfile", 0&, 0&, 0&)

        End If

        Kill sTempPath
    End If

End Function

Private Sub Command1_Click()
    'Английский
   Debug.Print GoogleSpeak("He said he hoped to catch someone dropping off 100 ballots or 50 ballots.", "en", True)
   
    'Немецкий
   'Debug.Print GoogleSpeak("Das Berliner Start-up Mietz mochte die Orientierung auf dem Mietmarkt mit einer App erleichtern.", "de", True)
   
    'Русский
   'Debug.Print GoogleSpeak("Privet. Horoshaya pogoda. Такие дела, брат. Цена - 553 raza.", "ru", True)
End Sub


The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Голосовое воспроизведение переводчика Google. Странное

Сообщение The trick » 30.10.2022 (Вс) 7:48

Не смотрел код, но уверен это из-за кодировки символов.
UA6527P

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Голосовое воспроизведение переводчика Google. Странное

Сообщение Хакер » 30.10.2022 (Вс) 10:05

VBChild писал(а):Нашёл в сети код воспроизведения текста, сервисом Google Translate.

А зачем? Завтра Google поменяет интерфейс взаимодействия с TTS-рендерером, и всё — пиши-пропало. Каждый день переделывать приложение из-за изменений, производимый Гуглом? К тому же, условия использования Гугла наверняка не резрешают подобных трюков. Могут и забанить пользователя за несанкционированные запросы.

Выложенный код очень плох сам по себе: никакой обработки ошибок, никакого отслеживания прогресса выполнения запроса. Да и про MCI я слышал, что его собираются ликвидировать (или уже ликвидировали) в новых версиях Windows.

У меня код не стал работать, URLDownloadToFile возвращала INET_E_DOWNLOAD_FAILURE (0x800C0008). Я догадался, что это из-за того, что urlmon.dll полагается на системную реализацию SSL/TLS, системная реализация не поддерживает последнюю версию TLS, а гугловский сервер настаивает именно на такой версии шифрования.

Я заменил https:// на http:// в аргументе для URLDownloadToFile, и это сработало — звук раздался, но это сработало только один раз. Дальнейшие попытки запуска функции давали уже ошибку E_ABORT (0x80004004).

Даже не знаю, с чем это связано. Перезапуск среды разработки исправил ситуацию, но это говорит о некоей ненадёжности URLDownloadToFile и библиотеки urlmon.dll.

Итак, пробное совершение запроса при включенном сниффере трафика Wireshark показало:

При передаче в качестве озвучиваемого текста строчки "Information. АБВГ. Test" HTTP-запрос выглядит вот так:
wireshark_abvg.png
wireshark_abvg.png (18.4 Кб) Просмотров: 596


Отсюда видим, что кириллические символы в составе URI передаются в составе GET-запроса тупо как байты, чьи значения соответствуют кодам кириллических символов в кодировки Windows-1251, что идёт в нарушение стандарта RFC 1738, который говорит о необходимости urlencode-ить все символы, кроме разрешённого множества abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~.

Даже если бы это было не запрещено, когда гугловский сервер видит байт со значением 192, откуда ему знать, что это буква «А», если это является буквой «А» только лишь в кодировке Windows-1251? Откуда гугловскому серверу знать, что мы предпочитаем кодировку Windows-1251?

Вывод:
Для правильного результата надо urlencode-ить строку запроса (URLDownloadToFile не делает этого самостоятельно для кириллических символов, мы видим что только пробел превратился в %20, но не кириллические символы), при этом механизм сопоставления символам кодовым значений должен быть таким, чтобы гугловский сервер смог выполнить обратное преобразование правильно. А это, в свою очередь, означает, что либо гугловский сервер ожидает от нас получить информацию об используемой кодировке, либо он предполагает, что мы используем Юникод, а значит мы должны передавать значения кодовых точек в рамках Юникода.

То есть, в случае использования Юникода, а точнее UTF-8, для озвучивания строки «Hello Хочу всё знать» надо передавать
Hello%20%D0%A5%D0%BE%D1%87%D1%83%20%D0%B2%D1%81%D1%91%20%D0%B7%D0%BD%D0%B0%D1%82%D1%8C
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

VBChild
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 29.10.2022 (Сб) 23:20

Re: Голосовое воспроизведение переводчика Google. Странное

Сообщение VBChild » 30.10.2022 (Вс) 23:57

Хакер, спасибо! Сделал, как ты сказал. Всё отлично заработало.

Осталась одна дилемма - найти параметр для tts гугла, отвечающий за скорость чтения. что-то вроде ttsspeed или speed, должно быть. Эти оба не работают.

Я заменил https:// на http:// в аргументе для URLDownloadToFile, и это сработало — звук раздался, но это сработало только один раз. Дальнейшие попытки запуска функции давали уже ошибку E_ABORT (0x80004004).

Не знаю. Я двое суток кодю и всё работает. И на работе сегодня раз 200 проигрывал и дома - вчера и сегодня.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Голосовое воспроизведение переводчика Google. Странное

Сообщение Хакер » 31.10.2022 (Пн) 10:18

VBChild писал(а):Не знаю. Я двое суток кодю и всё работает. И на работе сегодня раз 200 проигрывал и дома - вчера и сегодня.

Так надо тестировать на Windows XP, например, или более раннем чем-то.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex-бот и гости: 27

    TopList