Si, el código es básicamente el ejemplo de reconocimiento de texto sobre audio 
en streaming que tiene Google en su repo de github, solo que fallaba la parte 
del streaming cuando esta viene de un fichero y no de una fuente como un 
mícrófono. 

Al final conseguí resolverlo modificando la función de read_in_chunks, que como 
sospechaba era la culpable. Encontré la inspiración en las diapositivas de una 
conferencia de la PyCon 2008, que trataba específicamente el tema de iteradores 
y generadores. 

[ http://www.dabeaz.com/generators/Generators.pdf | 
http://www.dabeaz.com/generators/Generators.pdf ] 

La pista estaba en el parte cuando habla de "Part 5. Processing Infinite Data", 
página 72, en la página 75 está el ejemplo que me ayudó a resolver el problema. 

Sigo teniendo un pequeño fleco, que es que se queda intentando estremear el 
fichero incluso cuando ya se ha cerrado la grabación ... pero no me importa, 
porque genera una Excepción que es fácil capturar y hacer el clean_up de todo 
antes de acabar el procesado. 

Gracias por las pistas. 

> De: "lasizoillo" <lasizoi...@gmail.com>
> Para: "python-es" <python-es@python.org>
> Enviados: Viernes, 5 de Julio 2019 8:19:57
> Asunto: Re: [Python-es] Leer fichero al mismo tiempo que se está escribiendo 
> por
> otro proceso.

> Buenas,

> El código que has mandado tiene pinta de ser un corta y pega de tu código 
> real,
> por lo que nadie mas que tu va a poder reproducirlo. Así que lo único que veo
> viable es hablarte de las herramientas que usaría para investigarlo y que lo
> hagas tu mismo por tu cuenta.

> Usa un depurador
> --------------------------
> Python viene con pdb incluido, aquí tienes un depurador para usarlo [
> https://www.pybonacci.org/2013/06/14/como-depurar-un-programa-python-con-pdb/ 
> |
> https://www.pybonacci.org/2013/06/14/como-depurar-un-programa-python-con-pdb/ 
> ]
> Si usas algún IDE (por ejemplo pycharm) esto lo podrás hacer de una forma más
> visual. Con esto podrás ver si te está lanzando alguna excepción que estés
> enmascarando o ponerte a ejecutar código para ver información del fichero con
> os.stat() o lo que sea.

> Evalúa las llamadas al sistema
> ----------------------------------------------
> Dices tener un código en node.js que funciona, pero en python no. Es posible 
> que
> analizando llamadas al sistema de uno y otro código encuentres alguna
> diferencia que te sea inspiradora para encontrar tu problema. Puedes usar el
> comando de linux strace o el truss de freebsd u otros unix para encontrar las
> llamadas que se hacen.

> Prueba un cambio de paradigma
> -----------------------------------------------
> Quieres leer un fichero que está constantemente cambiando por lo que usar
> llamadas a sistema como kqueue en freebsd o inotify en linux pueden ayudarte a
> recibir eventos cuando el fichero cambie y leerlo entonces. Hay librerias
> dependiendo de tu SO (algunas son multiplataforma) para hacer un poco más 
> fácil
> esta tarea (por ejemplo pyinotify para linux). Con esto evitas tener que hacer
> pollings para ver si hay nuevos datos o no y solo lees cuando sabes que tienes
> nuevos datos en el fichero.

> Espero que algo de esto te sirva.

> Un saludo,

> Javi

> El jue., 4 jul. 2019 a las 21:17, Raúl Alexis Betancor Santana (< [
> mailto:r...@dimension-virtual.com | r...@dimension-virtual.com ] >) escribió:

>> El archivo no está vacío ... le he puesto un sleep de 2s para hacer pruebas
>> ANTES de abrir el fichero, y veo que en el FS tiene tamaño, así que de vacio
>> nada. Lo que no entiendo es porqué no lee absolutamente nada.

>>> De: "Daπid" < [ mailto:davidmen...@gmail.com | davidmen...@gmail.com ] >
>>> Para: "python-es" < [ mailto:python-es@python.org | python-es@python.org ] >
>>> Enviados: Jueves, 4 de Julio 2019 19:29:52
>>> Asunto: Re: [Python-es] Leer fichero al mismo tiempo que se está 
>>> escribiendo por
>>> otro proceso.

>>> El archivo está vacío, así que chunk es una cadena vacía. Esa función asume 
>>> que
>>> el archivo no está creciendo, así que cuando no lee más, el archivo está
>>> terminado.

>>> On Thu, 4 Jul 2019, 7:56 pm Raúl Alexis Betancor Santana, < [
>>> mailto:r...@dimension-virtual.com | r...@dimension-virtual.com ] > wrote:

>>>> Haciendo más pruebas, he llegado a la conclusión, de que lo que está mal 
>>>> es la
>>>> función de read_in_chunks ... ya que nunca lee nada y siempre acaba dentro 
>>>> del
>>>> if not chunk: break ... y no entiendo porque narices.

>>>> En todos los ejemplos que encuentro por la red para leer un fichero 
>>>> binario por
>>>> porciones, siempre usan mas o menos el mismo estilo de código para la 
>>>> función,
>>>> pero esta parece que nunca lee nada.

>>>> ¿Que estoy haciendo rematadamente mal, que no soy capaz de leer un fichero
>>>> binario a trozos? ... :-(

>>>>> De: "Raúl Alexis Betancor Santana" < [ mailto:r...@dimension-virtual.com |
>>>>> r...@dimension-virtual.com ] >
>>>>> Para: "python-es" < [ mailto:python-es@python.org | python-es@python.org 
>>>>> ] >
>>>>> Enviados: Jueves, 4 de Julio 2019 13:55:56
>>>>> Asunto: Re: [Python-es] Leer fichero al mismo tiempo que se está 
>>>>> escribiendo por
>>>>> otro proceso.

>>>>> No puedo, los ficheros los genera Asterisk y no voy a estar tocando el 
>>>>> código
>>>>> para eso.

>>>>> He probado añadiendo un delay de 250ms al inicio de la lectura, para darle
>>>>> tiempo a que haga un flush a disco, pero tampoco me vá.

>>>>> En realidad lo que me mosquea, es que un ejemplo que tengo en Node.js y 
>>>>> que hace
>>>>> exactamente lo mismo, funciona perfectamente, pero el código de python se 
>>>>> me
>>>>> queda en el for response in responses: ... osea, no llega nunca a recibir
>>>>> respuesta de GCS o el generador del read_in_chunks no está resolviendo o 
>>>>> algo
>>>>> raro.

>>>>> Ahora lo estoy intentando con ARI, porque llevo días intentandolo con un 
>>>>> script
>>>>> en python que ejecutaba desde el EAGI y tampoco había forma, o escuchaba 
>>>>> el
>>>>> stream de audio y lo interpretaba o reproducía una locución del IVR, pero 
>>>>> no
>>>>> ambas cosas al mismo tiempo y hacerlo vía threads, se me complicaba la 
>>>>> cosa,
>>>>> hacerlo vía multiprocess y pipes, tenía el problema de que tenía que estar
>>>>> leyendo desde el proceso hijo el FD 3 del proceso padre, un coñazo.

>>>>> Si ha alguien se le ocurre como resolver esto ... estoy abierto a ideas.

>>>>>> De: "Daπid" < [ mailto:davidmen...@gmail.com | davidmen...@gmail.com ] >
>>>>>> Para: "python-es" < [ mailto:python-es@python.org | python-es@python.org 
>>>>>> ] >
>>>>>> Enviados: Jueves, 4 de Julio 2019 11:57:11
>>>>>> Asunto: Re: [Python-es] Leer fichero al mismo tiempo que se está 
>>>>>> escribiendo por
>>>>>> otro proceso.

>>>>>> Creo que has encontrado la solución, pero la has puesto en el lugar 
>>>>>> equivocado.

>>>>>> #audio_file = io.open(stream_file+'.sln16','rb',buffering=0)

>>>>>> El proceso que está escribiendo al archivo está probablemente usando un 
>>>>>> buffer,
>>>>>> lo que quiere decir que sólo escribe al disco duro de vez en cuando, 
>>>>>> cuando
>>>>>> haya acumulado una cierta cantidad de datos. Si tienes acceso al 
>>>>>> programa que
>>>>>> escribe el archivo, tienes que o bien desactivar el buffer (¡cuidado con 
>>>>>> el
>>>>>> rendimiento!), usar uno más pequeño, o vaciarlo explícitamente con un 
>>>>>> flush()
>>>>>> más a menudo.

>>>>>> On Thu, 4 Jul 2019 at 12:28, Raúl Alexis Betancor Santana < [
>>>>>> mailto:r...@dimension-virtual.com | r...@dimension-virtual.com ] > wrote:

>>>>>>> Buenas, estoy intentando hechar a andar el Google Cloud Speech, he 
>>>>>>> intento leer
>>>>>>> en stream de un fichero que está siendo escrito por otro proceso, que 
>>>>>>> contiene
>>>>>>> la grabación del audio, para enviarla al GCS, pero sin éxito.

>>>>>>> ¿Alguien me puede comentar que estoy haciendo mal?, con el ejemplo que 
>>>>>>> da GCS
>>>>>>> para hacer lo mismo con un fichero directamente, que lo que hace es 
>>>>>>> leerlo
>>>>>>> completo en memoria y enviarlo, no me da problemas y transcribe bien el 
>>>>>>> texto.

>>>>>>> Basandome en el código de ejemplo de GCS para streaming

>>>>>>> def read_in_chunks(file_object,chunk_size):
>>>>>>> """Lazy function (generator) to read a file piece by piece.
>>>>>>> while True:
>>>>>>> chunk = file_object.read(chunk_size)
>>>>>>> if not chunk:
>>>>>>> return
>>>>>>> data = [chunk]
>>>>>>> yield b''.join(data)

>>>>>>> def transcribe_streaming(stream_file,language,timeout):
>>>>>>> """Streams transcription of the given audio file."""
>>>>>>> from google.cloud import speech
>>>>>>> from google.cloud.speech import enums
>>>>>>> from google.cloud.speech import types
>>>>>>> import io
>>>>>>> client = speech.SpeechClient()

>>>>>>> #audio_file = io.open(stream_file+'.sln16','rb',buffering=0)
>>>>>>> audio_file = io.open(stream_file+'.sln16','rb')
>>>>>>> # In practice, stream should be a generator yielding chunks of audio 
>>>>>>> data.
>>>>>>> requests = (types.StreamingRecognizeRequest(audio_content=chunk)
>>>>>>> for chunk in read_in_chunks(audio_file,3200))

>>>>>>> config = types.RecognitionConfig(
>>>>>>> encoding=enums.RecognitionConfig.AudioEncoding.LINEAR16,
>>>>>>> sample_rate_hertz=16000,
>>>>>>> language_code=language)
>>>>>>> #streaming_config =
>>>>>>> types.StreamingRecognitionConfig(config=config,single_utterance=True)
>>>>>>> streaming_config = types.StreamingRecognitionConfig(config=config)

>>>>>>> # streaming_recognize returns a generator.
>>>>>>> responses = client.streaming_recognize(streaming_config, requests)
>>>>>>> for response in responses:
>>>>>>> # Once the transcription has settled, the first result will contain the
>>>>>>> # is_final result. The other results will be for subsequent portions of
>>>>>>> # the audio.
>>>>>>> for result in response.results:
>>>>>>> if result.is_final:
>>>>>>> print('Finished: {}'.format(result.is_final))
>>>>>>> print('Stability: {}'.format(result.stability))
>>>>>>> alternatives = result.alternatives
>>>>>>> ### The alternatives are ordered from most likely to least.
>>>>>>> for alternative in alternatives:
>>>>>>> print('Confidence: {}'.format(alternative.confidence))
>>>>>>> print(u'Transcript: {}'.format(alternative.transcript))
>>>>>>> (null)
>>>>>>> _______________________________________________
>>>>>>> Python-es mailing list
>>>>>>> [ mailto:Python-es@python.org | Python-es@python.org ]
>>>>>>> [ https://mail.python.org/mailman/listinfo/python-es |
>>>>>>> https://mail.python.org/mailman/listinfo/python-es ]

>>>>>> _______________________________________________
>>>>>> Python-es mailing list
>>>>>> [ mailto:Python-es@python.org | Python-es@python.org ]
>>>>>> [ https://mail.python.org/mailman/listinfo/python-es |
>>>>>> https://mail.python.org/mailman/listinfo/python-es ]

>>>>> _______________________________________________
>>>>> Python-es mailing list
>>>>> [ mailto:Python-es@python.org | Python-es@python.org ]
>>>>> [ https://mail.python.org/mailman/listinfo/python-es |
>>>>> https://mail.python.org/mailman/listinfo/python-es ]

>>>> _______________________________________________
>>>> Python-es mailing list
>>>> [ mailto:Python-es@python.org | Python-es@python.org ]
>>>> [ https://mail.python.org/mailman/listinfo/python-es |
>>>> https://mail.python.org/mailman/listinfo/python-es ]

>>> _______________________________________________
>>> Python-es mailing list
>>> [ mailto:Python-es@python.org | Python-es@python.org ]
>>> [ https://mail.python.org/mailman/listinfo/python-es |
>>> https://mail.python.org/mailman/listinfo/python-es ]

>> _______________________________________________
>> Python-es mailing list
>> [ mailto:Python-es@python.org | Python-es@python.org ]
>> [ https://mail.python.org/mailman/listinfo/python-es |
>> https://mail.python.org/mailman/listinfo/python-es ]

> _______________________________________________
> Python-es mailing list
> Python-es@python.org
> https://mail.python.org/mailman/listinfo/python-es
_______________________________________________
Python-es mailing list
Python-es@python.org
https://mail.python.org/mailman/listinfo/python-es

Responder a