Send a Response with an inexact Content-Length header then manually end it
-
04-07-2021 - |
Question
I'm in a situation where I'm sending a file to an MP3 player, and this player needs to know the file length to show progress bar properly. The problem is that this MP3 comes from a file that is the result of an on-the-fly conversion, so I cannot know the final file size. Just an estimate (Bitrate * duration). So, when setting an erroneous Content-Length for the file, the file cannot be served, the download being hanging at the end with a network error.
Is there a way to force browsers to accept the data as final and as-is? For the player, this is not a problem, since it will probably just stops if it reaches an end sooner than it should.
[Edit]
For now, I'll try to add '00' bytes until I reach the good size and see how it is played.
Solution
Since I didn't need any ID3 tag information, the solution for this specific MP3 problem was to:
Use a tool like ffprobe.exe to get the duration
Remove 2 seconds to be sure to not reach the end of the real MP3 file with an unknown size before you have sent the number of bytes specified in your content-length header.
Then multiply by the bitrate, so you get the estimated size for the MP3 with an unknown size, then you remove some kbs.
Function getduration(ByVal url As String, ByVal curqual As Integer) As String Dim path As String = "C:\cmd\" Dim app As String = MapPath(".") & "\ffprobe.exe" Dim myProcess As New System.Diagnostics.Process() Dim AppPath As String = Request.PhysicalApplicationPath myProcess.StartInfo.FileName = app myProcess.StartInfo.Arguments = url myProcess.StartInfo.UseShellExecute = False myProcess.StartInfo.RedirectStandardOutput = True myProcess.StartInfo.RedirectStandardError = True myProcess.Start() Dim mystreamreader As StreamReader = myProcess.StandardError Dim str As String = mystreamreader.ReadToEnd Dim loca As Integer = str.IndexOf("Duration:") + 10 Dim locb As Integer = str.IndexOf(",", loca) Dim tm As String = str.Substring(loca, locb - loca) Dim tim As Integer = TimeSpan.Parse(tm).TotalMilliseconds Dim siz As Long = (((tim - 2000) * curqual) / 8) Return siz End Function