DEV Community

proxdam
proxdam

Posted on

Converter PDF em audiolivro usando python

Neste código, é apresentada uma implementação simples de um Audiobook a partir de um PDF. O texto do PDF é lido em formato de áudio para o usuário usando este código.

Introdução
Ler histórias, ensaios ou qualquer texto pode ser cansativo, no entanto, uma leitura em áudio do texto é conveniente e não exige tanta concentração quanto a leitura convencional. Neste projeto, implementei um conversor simples de PDF para áudio. Este código digitaliza página(s) de um PDF e o lê em formato de áudio para o usuário. Embora este projeto seja bom para a leitura de texto simples, ele não funciona bem se um artigo científico com equações for fornecido, porque as equações não são suportadas para leitura na biblioteca pytesseract OCR, que usamos para converter imagem em texto.

Fluxo do Projeto
Aqui está o diagrama do fluxo do projeto:

fluxo do projeto

Primeiro, pegamos o arquivo PDF e convertemos cada página em uma imagem usando o software PyMuPDF.
Em seguida, pegamos a(s) imagem(s) e digitalizamos o texto na imagem usando o software Pytesseract OCR.
Depois, usamos a biblioteca Google Text to Speech (gTTS) para converter o texto em um arquivo de áudio.
Por fim, utilizamos o Pygame mixer para reproduzir o arquivo de áudio em alto volume.

Software Pré-requisito
As bibliotecas de software necessárias para executar este código podem ser instaladas usando:

pip install -r requirements.txt
*Importe os módulos necessários para a conversão de texto em fala
*

from gtts import gTTS # Módulo para conversão de texto em fala
import pygame # Biblioteca para reprodução de áudio
from pygame import mixer # Submódulo para controle de áudio
from PIL import Image # Módulo para manipulação de imagens
import pytesseract # Módulo para reconhecimento óptico de caracteres (OCR)
import os # Módulo para operações do sistema de arquivos
import glob # Módulo para busca de arquivos
import PySimpleGUI as sg # Biblioteca para criar uma interface gráfica simples
import tkinter as tk # Módulo para criar janelas e diálogos
import fitz # Módulo para trabalhar com documentos PDF

Nesta função, obtemos a primeira e última página que desejamos que o software leia

def get_text(value):
string = value
string = string.strip()
if "-" in string:
first_page_number = int(string.split("-")[0])
last_page_number = int(string.split("-")[1])
else:
first_page_number = int(string)
last_page_number = 0
return first_page_number, last_page_number

def main():
global e, first_page_number, last_page_number

Cria um diretório para o software de texto para fala

current_directory = os.getcwd()
final_directory = os.path.join(current_directory, r'Text_to_speech_software')
if not os.path.exists(final_directory):
os.makedirs(final_directory)

Interface gráfica

layout = [[sg.Text('Escolha o arquivo PDF para ler'), sg.Input(), sg.FileBrowse()],
[sg.Text('Digite o número da página ou intervalo separado por - '), sg.InputText()],
[sg.Button('Ok'), sg.Button('Cancelar')]
]

Cria a janela da interface gráfica

window = sg.Window('Input', layout)
valid = False

while True:
event, values = window.read()
pdf_to_read = values[0]

if event in (None, 'Cancelar'):
    print("Saindo")
    window.close()
    exit()

if event == "Ok":
    if values[0] == "":
        sg.Popup("Digite um valor", "Digite o arquivo PDF a ser transcrito")
    if values[1] == "":
        sg.Popup("Digite um valor", "Digite o número(s) da página a ser transcrito")

    if values[0] != "" and values[1] != "":
        for char in values[1]:
            if char.isdigit() == False:
                sg.Popup("Valor inválido", "Digite um número válido ou números separados por -")
                break
            else:
                valid = True
                break

if valid == True:
    print('Você digitou ', values[1])
    break
Enter fullscreen mode Exit fullscreen mode

window.close()
first_page_number, last_page_number = get_text(values[1])

Remove arquivos antigos no diretório de imagens

image_directory = glob.glob(final_directory)
for file in os.listdir(final_directory):
filepath = os.path.join(final_directory, file)
os.chmod(filepath, 0o777)
os.remove(filepath)

Lê as páginas desejadas do PDF e as armazena como imagens em um diretório

doc = fitz.open(pdf_to_read)
k = 1
if last_page_number == 0:
page = doc.loadPage(first_page_number - 1)
zoom_x = 2.0
zoom_y = 2.0
mat = fitz.Matrix(zoom_x, zoom_y)
pix = page.getPixmap(matrix=mat)
output = os.path.join(final_directory, r"image_to_read.png")
pix.writePNG(output)
else:
for i in range(first_page_number - 1, last_page_number):
page = doc.loadPage(i)
zoom_x = 2.0
zoom_y = 2.0
mat = fitz.Matrix(zoom_x, zoom_y)
pix = page.getPixmap(matrix=mat)
output = os.path.join(final_directory, r"image_" + str(k) + "_to_read.png")
pix.writePNG(output)
k += 1

print("Concluído")

mytext = []

Carrega as imagens criadas na pasta Text_to_speech e lê o texto nas imagens usando OCR

for file in os.listdir(final_directory):
data = pytesseract.image_to_string(Image.open(os.path.join(final_directory, file)), lang="eng")
data = data.replace("|", "I")
data = data.split('\n')
mytext.append(data)

language = 'en'

print(mytext)

Garante que o texto seja lido corretamente, linha por linha

newtext = ""
for text in mytext:
for line in text:
line = line.strip()
if len(line.split(" ")) < 10 and len(line.split(" ")) > 0:
newtext = newtext + " " + str(line) + "\n"
elif len(line.split(" ")) < 2:
pass
else:
if line[-1] != ".":
newtext = newtext + " " + str(line)
else:
newtext = newtext + " " + line + "\n"

print(newtext)

Passa o texto e o idioma para o mecanismo, marcando slow=False para obter uma fala mais rápida

myobj = gTTS(text=newtext, lang=language, slow=False)

Salva o arquivo de áudio convertido como pdf_audio.mp3

myobj.save(os.path.join(final_directory, "pdf_audio.mp3"))

Carrega e reproduz o arquivo de áudio

pygame.init()
mixer.init()
mixer.music.load(os.path.join(final_directory, "pdf_audio.mp3"))
mixer.music.play()
pygame.event.wait()

if name == 'main':
main()

Em resumo, o código apresentou um desempenho satisfatório na leitura de arquivos PDF contendo texto convencional e direto. No entanto, quando o texto inclui equações matemáticas, o leitor não consegue interpretar essas equações de forma adequada. Portanto, podemos concluir que o código é eficaz para a leitura de textos simples, mas não é apropriado para lidar com documentos científicos que contenham equações complexas. No entanto, a leitura de texto comum é realizada com sucesso.

Top comments (0)