📜 ⬆️ ⬇️

SaveFrom.net + crutch, or download PLS playlists

Hi habrovtsy.
I think not only I have a big playlist on vk.com. Most recently, I was puzzled by how to deflate music in order to listen to it offline. Soon I found a convenient service SaveFrom.net . And all would be nothing, but only to pump out all the music at once, he does not know how. He offers us options:
1. Give us a bunch of url, so we put the whole thing in the download manager, such as DownloadManager
2. Save the playlist in m3u / pls, which play on url

In the first case, our file names will be 3ee56ab0933e.mp3. ID3 tag will be in place ( UPD is not for all songs there is a correct ID3Tag), but agree, it is inconvenient to open each song to see what it is
In the second case, we have pure urls in playlists, but the title is right away.

Since I didn’t want to watch files like 3ee56ab0933e.mp3, I also didn’t want to manually call it all — I sketched a tulza on my knee, which can read pls playlists, and download music in 10 connections.
')
Binary + source
The compiled executable + source code (in Delphi) is here



How to use
1. We scroll our playlist vkontakte to the bottom, so that SaveFrom.net can get a full pls
2. Choose download playlist:

3. In the window that appears, copy the playlist pls to the clipboard:

4. We insert this playlist into my utility in the field with the text Insert PLS text here:

5. Click the Download button, and see how the music starts to download.
6. If necessary, the VKMusic folder will be created in the program working directory. Folder name can be changed:

the path may be absolute.

If there is a daw in Allow skip files, then the program will check before downloading, if there is a file with the same name on the disk, then it will not download it.

A very brief digression to the source code.
I am writing first of all for those who want to change the code for themselves.
The program uses Virtual Treeview and Indy.
untPLSparser.pas - parser PLS files. In the interface of the module one single function:
function Parse(const text: string): TPLSItems; 
At the entrance - PLS playlist, returns an array of structures describing audio recordings (title + url + often track duration)

All this business is converted to another TMusicList array described in untDownloadList.pas.
TMusicList consists of TMusicItem and is needed to store information about the download status, as well as any errors that have occurred.

Next, the download process begins. 10 pre-created TDLThread threads, the implementation of which is located in untDownloadThread.pas, are starting to download compositions.
Downloading is launched via TfrmMain.RunFreeDownload in untMain.pas.
First, we get the index of the record to be downloaded using the TfrmMain.GetFreeItem method. Then we check if we have a daw to skip files, then see if there is such a file, and if there is, skip it.

In the process of downloading to callbacks
 DLProgress, DLError, DLComplete, DLTerminate 
Events arrive where we actually update the information in TMusicItem, start a new download or report an error.

Downloading streams work as follows.
After creation, the thread waits for download tasks in a loop:
  while (Url = '') do begin if Terminated then Exit; FInWork := False; Sleep(1); end; 
as soon as there is an url to download - it starts downloading. Since Indy is a library on blocking sockets, there must be a mechanism to stop loading. I use the special EStopTask exception in TidHTTP.OnWorkBegin, TidHTTP.OnWork, TidHTTP.OnWorkEnd callbacks, which allows me to actually interrupt the download at any time.

If something went wrong, but we can correctly process it, and continue to work, we process, we file the under-downloaded file. If an exception has arisen in the stream that we cannot handle (for example, AV), then according to the standard mechanism, the stream will be nailed, and the exception object will lie in the FatalException. Therefore, in untMain.pas, I process OnTerminate, check the thread's exception object, and if it does, throw an exception already in the main thread.

Finally

That's all, thanks for reading. I am glad if my “crutch” suddenly turned out to be convenient for you.

Source: https://habr.com/ru/post/187240/


All Articles