Converter PDF em audiolivro usando python
Tags: python, books, audio
Published: 2023-09-05 04:51:55

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

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.**