Hello,
I am writing a multi-threaded Java application for video conversion and uploading to YouTube. I came across a strange feature - it’s even a plus, that is, it doesn’t bother me at all, but I understand that this is a consequence of an error and a curved design, and I want to understand where he did the stupidity.
There are several threads in the application:
- the thread that starts the FFMpeg encoder process, takes data from its output (console buffer) - the class is inherited from Thread;
- the thread that starts this thread, and binds to it via waitFor () - ServiceRunner, the class is inherited from Thread;
- the main thread - in a loop on some timer checks whether the stop flag is set (if set, knocks the ffmpeg system process, since there is no other way to complete it, and performs finalization, calling the necessary logic of other classes;
- flow processing SwingUI, interface rendering;
- in the "only download without conversion" mode, there is another stream that updates the Elapsed time and Remaining time counters once a second by a timer;
- Browser stream (extends Thread) - upload data to YouTube and access API, uses Apache HttpClient
Everything works quite predictably (except for small nuances like the fact that at the time of stopping due to the curved code, states in different classes may not be coordinated), except for one strange moment.
Namely, at startup, all threads (ServiceRunner and Main) are blocked until the launched HttpConnect stream (the static inner class inside the Browser) receives data. This HttpConnect is an embedded, simplest web server type. Its task is to accept the access token from YouTube sent by the link in the redirect. And display a link to the video control panel so that the user can use the open tab with benefit.
And here it is strange: a new thread starts, a socket is returned to the class constructor, returned via accept (), the similar code worked in most other projects. But here it does not work that way. Namely, until this socket receives the data, the encoding does not start. StreamGobbler, which receives data from ffmpeg, and in this mode also launches the Browser (since it didn’t work out from Main, all code wasn’t executed after the start of this stream) is not executed. As the debug output showed, the loop with timers in Main is not executed either. Nothing is executed except the stream where the code of the Browser class is executed. UI, however, works.
And because of this, we cannot start coding until the user gives the application access to YouTube. In the combined mode it may even be logical, but we are losing precious time. And they could do useful work.
How can I rewrite the code so that there is no problem?