epub_to_audiobook icon indicating copy to clipboard operation
epub_to_audiobook copied to clipboard

Gradio Web UI

Open Bryksin opened this issue 1 year ago • 10 comments

  • Implement Web UI request. Closes: #15 Ticket / Closes: #24 PR
  • Update Piper TTS
    • now it is a single TTS provided
    • implements the Docker approach
    • implementers Local install appraoch with automatic voice model downloading functionality
    • list all languages/voices /quality/readers
  • Update Azure provider: list all supported languages/voices/output formats - required for UI
  • Update Edge provider: list supported languages/voices - required for UI
  • Update docker file / compose and entrypoint
  • Update requirements

New Piper implementation is fully tested (Docker and Local) New UI defiantly requires more testing

Bryksin avatar Apr 04 '25 16:04 Bryksin

I started trying this new WebUI, but the installation didn't seem particularly smooth, possibly due to environment issues. I will try to document the problems encountered during the process and their solutions.

p0n1 avatar Apr 09 '25 03:04 p0n1

After installed new dependencies by pip install -r requirements.txt, I ran python main_ui.py and got ModuleNotFoundError:

> python main_ui.py
Traceback (most recent call last):
  File "/Users/p0n1/epub_to_audiobook/main_ui.py", line 4, in <module>
    from audiobook_generator.ui.web_ui import host_ui
  File "/Users/p0n1/epub_to_audiobook/audiobook_generator/ui/web_ui.py", line 4, in <module>
    from tkinter import Tk, filedialog
  File "/opt/homebrew/Cellar/[email protected]/3.10.16/Frameworks/Python.framework/Versions/3.10/lib/python3.10/tkinter/__init__.py", line 37, in <module>
    import _tkinter # If this fails your Python may not be configured for Tk
ModuleNotFoundError: No module named '_tkinter'

Related: https://stackoverflow.com/questions/5459444/tkinter-python-may-not-be-configured-for-tk

https://github.com/p0n1/epub_to_audiobook/blob/4babae80de948d44404d31f9734a15d85954d5de/audiobook_generator/ui/web_ui.py#L4

Fixed bybrew install [email protected] on MacOS for me. The @3.10 is need because I have multiple python versions on my system.

p0n1 avatar Apr 09 '25 03:04 p0n1

The UI started, then I chose to select the book file to process and got NSInternalInconsistencyException:

> python main_ui.py
* Running on local URL:  http://127.0.0.1:7860

To create a public link, set `share=True` in `launch()`.
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'NSWindow should only be instantiated on the main thread!'
*** First throw call stack:
(
	0   CoreFoundation                      0x000000018597ae80 __exceptionPreprocess + 176
	1   libobjc.A.dylib                     0x0000000185462cd8 objc_exception_throw + 88
	2   CoreFoundation                      0x000000018599f534 _CFBundleGetValueForInfoKey + 0
	3   AppKit                              0x0000000189490460 -[NSWindow _initContent:styleMask:backing:defer:contentView:] + 260
	4   AppKit                              0x0000000189490350 -[NSWindow initWithContentRect:styleMask:backing:defer:] + 48
	5   libtk8.6.dylib                      0x0000000103d93b5c TkMacOSXMakeRealWindowExist + 496
	6   libtk8.6.dylib                      0x0000000103d9385c TkWmMapWindow + 56
	7   libtk8.6.dylib                      0x0000000103d04ffc MapFrame + 76
	8   libtcl8.6.dylib                     0x0000000103ac447c TclServiceIdle + 84
	9   libtcl8.6.dylib                     0x0000000103aa85d0 Tcl_DoOneEvent + 296
	10  libtk8.6.dylib                      0x0000000103d8781c TkpInit + 712
	11  libtk8.6.dylib                      0x0000000103cfe030 Initialize + 2372
	12  _tkinter.cpython-310-darwin.so      0x0000000103866328 Tcl_AppInit + 80
	13  _tkinter.cpython-310-darwin.so      0x0000000103860298 Tkapp_New + 592
	14  _tkinter.cpython-310-darwin.so      0x000000010385fc6c _tkinter_create + 608
	15  Python                              0x0000000103379ac8 cfunction_vectorcall_FASTCALL + 88
	16  Python                              0x000000010340a128 call_function + 128
	17  Python                              0x0000000103406600 _PyEval_EvalFrameDefault + 30908
	18  Python                              0x00000001033fde7c _PyEval_Vector + 396
	19  Python                              0x00000001033318d4 _PyObject_FastCallDictTstate + 96
	20  Python                              0x0000000103397e5c slot_tp_init + 200
	21  Python                              0x000000010338ffb0 type_call + 288
	22  Python                              0x000000010333157c _PyObject_MakeTpCall + 136
	23  Python                              0x000000010340a1b8 call_function + 272
	24  Python                              0x000000010340662c _PyEval_EvalFrameDefault + 30952
	25  Python                              0x00000001033fde7c _PyEval_Vector + 396
	26  Python                              0x000000010340a128 call_function + 128
	27  Python                              0x000000010340662c _PyEval_EvalFrameDefault + 30952
	28  Python                              0x00000001033fde7c _PyEval_Vector + 396
	29  Python                              0x00000001034067c4 _PyEval_EvalFrameDefault + 31360
	30  Python                              0x00000001033fde7c _PyEval_Vector + 396
	31  Python                              0x000000010341da00 _PyObject_VectorcallTstate.4692 + 88
	32  Python                              0x000000010341d8bc context_run + 92
	33  Python                              0x0000000103379a18 cfunction_vectorcall_FASTCALL_KEYWORDS + 84
	34  Python                              0x00000001034067c4 _PyEval_EvalFrameDefault + 31360
	35  Python                              0x00000001033fde7c _PyEval_Vector + 396
	36  Python                              0x000000010340a128 call_function + 128
	37  Python                              0x000000010340658c _PyEval_EvalFrameDefault + 30792
	38  Python                              0x00000001033fde7c _PyEval_Vector + 396
	39  Python                              0x000000010340a128 call_function + 128
	40  Python                              0x000000010340658c _PyEval_EvalFrameDefault + 30792
	41  Python                              0x00000001033fde7c _PyEval_Vector + 396
	42  Python                              0x0000000103334944 method_vectorcall + 392
	43  Python                              0x00000001034a681c thread_run + 120
	44  Python                              0x0000000103458708 pythread_wrapper + 48
	45  libsystem_pthread.dylib             0x00000001858202e4 _pthread_start + 136
	46  libsystem_pthread.dylib             0x000000018581b0fc thread_start + 8
)
libc++abi: terminating due to uncaught exception of type NSException
[1]    26276 abort      python main_ui.py

p0n1 avatar Apr 09 '25 03:04 p0n1

The UI started, then I chose to select the book file to process and got NSInternalInconsistencyException:

Looks like macOS specific issue related to tk. I'll try to fix this.

p0n1 avatar Apr 09 '25 03:04 p0n1

The UI started, then I chose to select the book file to process and got NSInternalInconsistencyException:

Looks like macOS specific issue related to tk. I'll try to fix this.

@Bryksin I fixed this by removing the usage of tkinter and using the Gradio native file processing function. Then I even don't need to install this python-tk manually https://github.com/p0n1/epub_to_audiobook/pull/132#issuecomment-2788200423. No sure if we have a specific reason to use tkinter.

I'm not pushing the fix commit from my side directly. Just in case you have some reason or this fix won't work on your environment.

Here is my fix. https://gist.github.com/p0n1/d50b41e0c066b74248149372e51fb973/revisions

p0n1 avatar Apr 09 '25 10:04 p0n1

Hi @p0n1 I was developing that change in Windows, and that tkinter was available somehow out of the box. I didn't install it on purpose; that's why I didn't add it even to the requirements.txt, as I was thinking its default package of the python

The reason behind adding it - because the gradio File element is very dumb and limited. It is ok for the file selection, but not ok for the folder selection, plus in UI file element by some reason doesn't resise correctly like other elements, looks a bit bulki and break overall UI layout.

As I see in your change for the folder part you just left it as textbox where user will have to manually enter the path - instead of browse and select, it could be a solution, though not so user-friendly like with tk

is it general problem with tk on Macs? or only your own PC problem? anyway, if it requires additional OS level packages installation outside of requirements.txt - it is not good, and maybe sacrafise of the UI usability is a good tradeoff, from the other side we introduced docker and I would expect that most of the people will use docker as its simpleier then checkouting project, especially now with web UI, and in docker we can control all those OS dependencies

I don't know, what are your thoughts? but if we continue using tk it definitely must be added to the requirements.txt as it seems not default python package

Bryksin avatar Apr 10 '25 08:04 Bryksin

is it general problem with tk on Macs? or only your own PC problem? anyway, if it requires additional OS level packages installation outside of requirements.txt - it is not good, and maybe sacrafise of the UI usability is a good tradeoff, from the other side we introduced docker and I would expect that most of the people will use docker as its simpleier then checkouting project, especially now with web UI, and in docker we can control all those OS dependencies

I think it's a general issue with tk on Mac and Linux. Check https://pytutorial.com/how-to-fix-modulenotfounderror-no-module-named-tkinter-in-python/. Users will have to install tk on system level. So adding it to requirements.txt won't help too much.

There was another NSInternalInconsistencyException issue I mentioned above. I did actually find a fix for this before, which had to do with specific issues you need to watch out for when using tk in the macOS environment. However, the code for the fix was a bit of a hassle, so I switched to not using tk.

As I see in your change for the folder part you just left it as textbox where user will have to manually enter the path - instead of browse and select, it could be a solution, though not so user-friendly like with tk

Given its complexity, I'd rather remove the dependency on tk. I didn't realize Gradio's File component only lets us select files. Let me look into it more.

p0n1 avatar Apr 14 '25 02:04 p0n1

Given its complexity, I'd rather remove the dependency on tk. I didn't realize Gradio's File component only lets us select files. Let me look into it more.

Looks like we still can't take folder as input https://github.com/gradio-app/gradio/issues/2515. Either letting the user input the path manually or generating a default one for them seems acceptable to me.

p0n1 avatar Apr 14 '25 04:04 p0n1

Oh, you still didn't merge, sorry, I was on holiday. Lsn, then just take your fix, apply and merge, no point to wait so long. If tk cause so many problems then users will be copy/pasting the path manually, not a big deal :)

Bryksin avatar Apr 27 '25 08:04 Bryksin

Thanks. I'll move on.

p0n1 avatar Apr 28 '25 04:04 p0n1