Type MediaFile(FileName As String, FileType As String, Subdir As String, Duration As String, Thumbnail As String)
Public MediaFiles As List 'All available media files as customtype MediaFile
'Retrieves every file found in the Media folder and stores it for later use.
Public Sub GetAllFilesRecursive As ResumableSub
MediaFiles.Clear
Main.ckvs.Put("CMS3K", "MediaFiles", Null) 'Delete old cache DB Record.
If File.ListFiles(MediaDIR).Size = 0 Then Return False 'No Files Found
Files.Clear 'Clear our cached files before we begin to recache
Folders.Clear 'Clear our cached directories before we begin to recache
ReadMediaDir(MediaDIR, True) 'Get all files and folders, Parse and store only Media Files.
Wait For (BuildAllMediaFiles) Complete (Result As Boolean)
Return True
End Sub
'Build the Thumbnails, Duration of video files (if applicable).
Public Sub BuildAllMediaFiles As ResumableSub
Dim I As Int
I = 0
IncompatibleVideoDetected = False
Main.ckvs.Put("CMS3K", "MediaFiles", Null) 'Remove existing record of media file cache.
MediaType.InitializeStatic("com.google.common.net.MediaType")
For Each MF As MediaFile In MediaFiles
Wait For (BuildMediaFile(MF)) Complete (Result As MediaFile)
MF = Result
I = I + 1
If SubExists(Callback, "FileManager_BuildMediaStatus") = True Then
CallSub2(Callback, "FileManager_BuildMediaStatus", Array As Int(MediaFiles.Size, I))
Else
Log("Unhandled BuildMediaStatus Event Caught")
End If
Next
Main.ckvs.Put("CMS3K", "MediaFiles", MediaFiles) 'Update cache DB record.
Return True
End Sub
'Get the thumbnail, duration of the media file.
Public Sub BuildMediaFile(MF As MediaFile) As ResumableSub
If MediaType.RunMethodJO("parse",Array(MF.FileType)).RunMethod("is",Array(MediaType.GetField("ANY_IMAGE_TYPE"))) = True Then 'It is an Image File
Dim ThumbNailImage As Image
ThumbNailImage.InitializeSample(MediaDIR & MF.Subdir, MF.FileName, 320, 240)
MF.Thumbnail = BitmapToBase64(ThumbNailImage) 'This takes alot of String space. Maybe a better way?
Else If MediaType.RunMethodJO("parse",Array(MF.fileType)).RunMethod("is",Array(MediaType.GetField("ANY_VIDEO_TYPE"))) = True Then 'It is a video file
Dim rs As ResumableSub = GenerateVideoDetails(MF.FileName, MF.Subdir)
Wait For (rs) Complete (Result As Object)
If Result Is Boolean Then 'We returned a fault from GenerateVideoDetails, either a corrupt file or the file was in use.
MF.Thumbnail = "failed"
MF.Duration = ""
Else 'We got a good reply
Dim Arr() As String = Result
MF.Duration = Arr(0)
MF.Thumbnail = Arr(1)
End If
If Left(MF.FileType, 5) = "video" And MF.FileType <> "video/mp4" Then 'We have detected an incompatible file type, raise the flag so the operator can convert.
IncompatibleVideoDetected = True
End If
End If
Return MF
End Sub
'Generates the video thumbnail and video duration from FFMpeg
Private Sub GenerateVideoDetails(FileName As String, FilePath As String) As ResumableSub
Dim sh1 As Shell
If File.Exists(File.DirTemp, "thumb.png") = True Then File.Delete(File.DirTemp, "thumb.png") 'Remove the file
sh1.Initialize("sh1", "ffmpeg", Array As String("-i", MediaDIR & FilePath & "/" & FileName, "-vf", "thumbnail,scale=320:240", "-frames:v", "1", File.DirTemp & "/" & "thumb.png")) 'Grab the duration and thumbnail from the media file
sh1.WorkingDirectory = File.DirApp
sh1.Run(10000)
Wait For sh1_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
If Success = False Then
Return False
Else
Try 'Parse Duration from Response Text. ffmpeg outputs on STDErr for some reason. So we will use a sum of both stdout and stderr.
Dim StdOutErr As String = StdOut & StdErr
Dim Response() As String = Regex.Split("Duration:", StdOutErr)
Dim Duration() As String = Regex.Split(",", Response(1))
Catch 'Failed to parse the correct duration information. Maybe passed a bad file?
Return False
End Try
Dim bmp As Image
bmp.Initialize(File.DirTemp, "thumb.png")
Return Array As String(Duration(0), BitmapToBase64(bmp))
End If
End Sub
Private Sub ReadMediaDir(folder As String, recursive As Boolean)
Dim lst As List = File.ListFiles(folder)
MediaType.InitializeStatic("com.google.common.net.MediaType")
For i = 0 To lst.Size - 1
If File.IsDirectory(folder,lst.Get(i)) Then
Dim v As String
v = folder & "/" & lst.Get(i)
Folders.Add(v.SubString(MediaDIR.Length+1))
If recursive Then
ReadMediaDir(v,recursive) 'Very similar to "goto" Re-runs the same sub inside the sub.
End If
Else
Dim fileType As String = asJO(Me).RunMethod("getType",Array(folder & "/" & lst.Get(i))) 'Get the MIME Type of the file
If MediaType.RunMethodJO("parse",Array(fileType)).RunMethod("is",Array(MediaType.GetField("ANY_IMAGE_TYPE"))) = True Or _
MediaType.RunMethodJO("parse",Array(fileType)).RunMethod("is",Array(MediaType.GetField("ANY_VIDEO_TYPE"))) = True Then 'If the file is a usable video or image file we parse it further
Dim MF As MediaFile
MF.Initialize
MF.FileName = lst.Get(i)
MF.FileType = fileType
MF.Subdir = folder.SubString(MediaDIR.Length)
MediaFiles.Add(MF)
Main.ckvs.Put("CMS3K", "MediaFiles", MediaFiles) 'Update DB Record
End If
Files.Add(folder & "/" & lst.Get(i))
End If
Next
End Sub