@@ -5,6 +5,8 @@ const fs = require('fs');
55const path = require ( 'path' ) ;
66const os = require ( 'os' ) ;
77const https = require ( 'https' ) ; // Add this import
8+ const { v4 : uuidv4 } = require ( 'uuid' ) ;
9+
810
911const expressApp = express ( ) ;
1012let serverPort , ytWin ;
@@ -80,11 +82,23 @@ function ensureFile(filePath, url) {
8082}
8183
8284function parseVideoFormats ( output ) {
83- const filtered = output . split ( '\n' ) . filter ( line =>
84- line . trim ( ) && ! / (?: \[ | \] | D o w n l o a d i n g | A v a i l a b l e f o r m a t s | I D | - - - - - - - - - - - - - - - - - - - ) / . test ( line )
85- ) ;
85+ const filtered = output . split ( '\n' ) . filter ( line => {
86+ line = line . trim ( ) ;
87+ if ( ! line ) return false ;
88+ if ( / ( D o w n l o a d i n g | A v a i l a b l e f o r m a t s | I D | - - - - - - - - - - - - - - - - - - - ) / . test ( line ) ) return false ;
89+ const matches = line . match ( / \[ [ ^ \] ] * \] / g) ;
90+ if ( matches ) {
91+ for ( const m of matches ) {
92+ const content = m . slice ( 1 , - 1 ) ;
93+ // Allow only if content has exactly two letters.
94+ if ( ! / ^ [ A - Z a - z ] { 2 } $ / . test ( content ) ) return false ;
95+ }
96+ }
97+ return true ;
98+ } ) ;
8699
87100 const result = filtered . map ( line => {
101+ if ( line . toLowerCase ( ) . includes ( 'quic' ) ) return null ; // Skip lines containing 'quic'
88102 let parts = line . split ( / \s { 2 , } / ) . map ( x => x . trim ( ) ) . flatMap ( part =>
89103 part . split ( '|' ) . map ( x => x . trim ( ) ) . filter ( Boolean )
90104 ) ;
@@ -101,7 +115,7 @@ function parseVideoFormats(output) {
101115 }
102116 }
103117 return parts ;
104- } ) . filter ( parts => parts . length > 1 && ! parts . includes ( 'images' ) ) ;
118+ } ) . filter ( parts => parts && parts . length > 1 && ! parts . includes ( 'images' ) ) ;
105119
106120 // Remove duplicate entries
107121 const unique = Array . from ( new Set ( result . map ( a => JSON . stringify ( a ) ) ) ) . map ( e => JSON . parse ( e ) ) ;
@@ -178,13 +192,13 @@ expressApp.get('/get_vid_options', (req, res) => {
178192
179193 if ( ! videoUrl ) return res . status ( 400 ) . send ( 'Missing "url" parameter' ) ;
180194
181- let cookiePart = videoUrl . includes ( "youtube.com" )
195+ let parameters = videoUrl . includes ( "youtube.com" )
182196 ? ` --cookies "${ path . join ( userDataDir , 'yt-cookie.txt' ) } "`
183197 : '' ;
184- cookiePart = vimeoPass
198+ parameters = vimeoPass
185199 ? ` --video-password "${ vimeoPass } "`
186200 : '' ;
187- const command = `"${ path . join ( executablesDir , 'yt-dlp-mac' ) } "${ cookiePart } -F "${ videoUrl } "` ;
201+ const command = `"${ path . join ( executablesDir , 'yt-dlp-mac' ) } "${ parameters } -F "${ videoUrl } "` ;
188202
189203 exec ( command , { encoding : 'utf8' , maxBuffer : 1024 * 1024 } , ( error , stdout ) => {
190204 if ( error ) {
@@ -193,7 +207,6 @@ expressApp.get('/get_vid_options', (req, res) => {
193207 }
194208 try {
195209 const parsed = parseVideoFormats ( stdout ) ;
196- console . log ( parsed ) ;
197210 res . send ( parsed ) ;
198211 } catch ( e ) {
199212 console . error ( e ) ;
@@ -202,6 +215,49 @@ expressApp.get('/get_vid_options', (req, res) => {
202215 } ) ;
203216} ) ;
204217
218+ expressApp . get ( '/download_vid' , ( req , res ) => {
219+ const videoUrl = req . query . url ;
220+ const vimeoPass = req . query . vimeoPass ;
221+ const videoFormat = req . query . id ;
222+ const videoType = req . query . type ;
223+
224+ if ( ! videoUrl ) return res . status ( 400 ) . send ( 'Missing "url" parameter' ) ;
225+ if ( ! videoFormat ) return res . status ( 400 ) . send ( 'Missing "format" parameter' ) ;
226+
227+ let parameters = videoUrl . includes ( "youtube.com" )
228+ ? ` --cookies "${ path . join ( userDataDir , 'yt-cookie.txt' ) } "`
229+ : '' ;
230+ parameters = vimeoPass && vimeoPass !== undefined
231+ ? ` --video-password "${ vimeoPass } "`
232+ : '' ;
233+
234+ if ( videoFormat . includes ( 'vid' ) && videoFormat . includes ( 'aud' ) ) {
235+ const video_download_id = uuidv4 ( ) ;
236+ const audio_download_id = uuidv4 ( ) ;
237+ const [ videoId , audioId ] = videoFormat
238+ . split ( ',' )
239+ . map ( part => part . split ( ':' ) [ 1 ] . trim ( ) ) ;
240+
241+ } else {
242+ const video_download_id = uuidv4 ( ) ;
243+
244+ const command = `"${ path . join ( executablesDir , 'yt-dlp-mac' ) } "${ parameters } -f "${ videoFormat } " "${ videoUrl } " -o "${ path . join ( baseDir , 'OutputFiles' ) } /${ video_download_id } .${ videoType } "` ;
245+ exec ( command , { encoding : 'utf8' , maxBuffer : 1024 * 1024 } , ( error , stdout ) => {
246+ if ( error ) {
247+ console . error ( error ) ;
248+ return res . status ( 500 ) . send ( 'Error downloading video' ) ;
249+ }
250+ try {
251+ const download_path = `${ path . join ( baseDir , 'OutputFiles' ) } /${ video_download_id } .${ videoType } `
252+ res . send ( JSON . stringify ( { download_path } ) ) ;
253+ } catch ( e ) {
254+ console . error ( e ) ;
255+ res . status ( 500 ) . send ( 'Error downloading video' ) ;
256+ }
257+ } ) ;
258+ }
259+ } ) ;
260+
205261expressApp . get ( '/show_supported_list' , ( req , res ) => {
206262 createListWindow ( ) ;
207263 res . send ( 'Success' ) ;
@@ -235,6 +291,10 @@ app.whenReady().then(() => {
235291 path . join ( executablesDir , 'yt-dlp-mac' ) ,
236292 'https://jemcats.software/github_pages/VideoSnatcher/files/yt-dlp-mac'
237293 ) ;
294+ ensureFile (
295+ path . join ( executablesDir , 'ffmpeg-mac' ) ,
296+ 'https://jemcats.software/github_pages/VideoSnatcher/files/ffmpeg-mac'
297+ ) ;
238298 createMainWindow ( ) ;
239299} ) ;
240300
0 commit comments