#COMPILE EXE #DIM ALL '------------------------------------------------------------------------------------- DECLARE FUNCTION URLDownloadToFile LIB "urlmon.dll" ALIAS "URLDownloadToFileA" _ (BYVAL pCaller AS DWORD, szURL AS ASCIIZ, szFileName AS ASCIIZ, _ BYVAL dwReserved AS DWORD, BYVAL fnCB AS DWORD) AS LONG '------------------------------------------------------------------------------------- '------------------------------------------------------------------------------------- FUNCTION TimeStamp() AS STRING LOCAL d, t AS STRING d = DATE$ t = TIME$ FUNCTION = RIGHT$(d,4)+LEFT$(d,2)+MID$(d,4,2)+"-"+REMOVE$(t,":") END FUNCTION '------------------------------------------------------------------------------------- '------------------------------------------------------------------------------------- FUNCTION MediaName(BYVAL url AS STRING) AS STRING LOCAL i AS LONG i = INSTR(-1, url, "/") FUNCTION = MID$(url, i+1) END FUNCTION '------------------------------------------------------------------------------------- '------------------------------------------------------------------------------------- FUNCTION ResumeWhere(BYVAL vid AS STRING, BYVAL start AS LONG) AS LONG LOCAL e AS STRING LOCAL i AS LONG i = start DO e = vid : REPLACE "#" WITH TRIM$(STR$(i)) IN e e = DIR$(e) : DIR$ CLOSE IF e <> "" THEN INCR i ELSE DECR i LOOP UNTIL e = "" FUNCTION = i END FUNCTION '------------------------------------------------------------------------------------- '------------------------------------------------------------------------------------- FUNCTION GrabFile(BYVAL file AS STRING) AS STRING LOCAL buf AS STRING LOCAL ff AS LONG ff = FREEFILE OPEN file FOR BINARY AS #ff GET$ #ff, LOF(#ff), buf CLOSE #ff FUNCTION = buf END FUNCTION '------------------------------------------------------------------------------------- '------------------------------------------------------------------------------------- FUNCTION PBMAIN () AS LONG LOCAL ff, i, j, a, a0, b, ffmpeg AS LONG LOCAL url, vid, e, r AS STRING e = DIR$("ffmpeg.exe") : DIR$ CLOSE ffmpeg = (e <> "") e = COMMAND$ i = INSTR(-1, e, $SPC) j = INSTR(i+1, e, "-") IF INSTR(e, "#") = 0 OR i = 0 OR j= 0 THEN ? "Usage: ts2mp4 https://my.stream/media_#.ts 1-999" ? " > will download media_1.ts to media_999.ts" ? " > from the mentioned url, concatenate all" ? " > streams, and convert to mp4" ? " " ? "Needed: ffmpeg.exe (~64MB) in same folder as exe" ? " " EXIT FUNCTION END IF url = LEFT$(e, i-1) vid = MediaName(url) e = MID$(e, i+1) j = INSTR(e, "-") a = VAL(LEFT$(e, j-1)) b = VAL(MID$(e, j+1)) a0 = a e = vid : REPLACE "#" WITH TRIM$(STR$(a)) IN e e = DIR$(e) : DIR$ CLOSE IF e <> "" THEN ? "A previous session was detected. Resuming download..." a0 = ResumeWhere(vid, a) END IF FOR i = a0 TO b ? "Downloading stream part #" + TRIM$(STR$(i)) + " / " + TRIM$(STR$(b)) e = url : REPLACE "#" WITH TRIM$(STR$(i)) IN e j = URLDownloadToFile (BYVAL 0, (e), MediaName(e), 0, BYVAL 0) IF j <> 0 THEN ' error download ? "! Error downloading " + e EXIT FUNCTION END IF NEXT ? " " e = REMOVE$(vid, "#") : i = INSTR(-1, e, ".") : e = LEFT$(e, i) IF ISTRUE ffmpeg THEN ? "Download OK! Generating '" + e + "lst'" ff = FREEFILE OPEN e + "lst" FOR OUTPUT AS #ff FOR i = a TO b e = vid : REPLACE "#" WITH TRIM$(STR$(i)) IN e PRINT #ff, "file '" + e + "'" NEXT CLOSE #ff e = REMOVE$(vid, "#") : i = INSTR(-1, e, ".") : e = LEFT$(e, i) ? "Concatenating streams..." ? "ffmpeg -f concat -i " + e + "lst -c copy " + e + "ts" SHELL "ffmpeg -f concat -i " + e + "lst -c copy " + e + "ts" ? "Converting to mp4..." ? "ffmpeg -i " + e + "ts -acodec copy -vcodec copy " + e + "mp4" SHELL "ffmpeg -i " + e + "ts -acodec copy -vcodec copy " + e + "mp4" ELSE ' No ffmpeg on local ? "'ffmpeg.exe' not found > using backup internal mode, the result may not be a valid mp4!" ? "Manually concatenating streams..." ff = FREEFILE OPEN e + "mp4" FOR BINARY AS #ff FOR i = a TO b e = vid : REPLACE "#" WITH TRIM$(STR$(i)) IN e PUT$ #ff, GrabFile(e) NEXT CLOSE #ff END IF ? " " ? "Converting done! Cleaning up..." FOR i = a TO b e = vid : REPLACE "#" WITH TRIM$(STR$(i)) IN e KILL e NEXT e = REMOVE$(vid, "#") : i = INSTR(-1, e, ".") : e = LEFT$(e, i) KILL e + "lst" KILL e + "ts" ? " " ? "All done. Thanks for using ts2mp4!" ? "Visit http://mougino.free.fr for other open source software." ? " " END FUNCTION '-------------------------------------------------------------------------------------