Reputation: 9
I am trying to develop a console app that can record the screen and have cpu/ram/gpu usage of the machine noted on the recording. The problem i am facing is that after a while (2-3 hours) the recording stops because ffmpeg is trying to read the file text while my C# code tries to update the file. I managed to find out that I should use a temp file and replace the original instead of rewriting the whole file but that way I encounter another problem, ffmpeg will try to read the file while the file is replaced or even for that split second when is considered deleted. Any ideas what I should do? How should the method with the temp file be managed or how can I make the method that updates the same file stable? I was even thinking to increment the ffmpeg reload frames since it might narrow the chances of crashing but it's not a 100% crash proof solution.
Error message received from ffmpeg with updating only the text from the file:
Error: [Parsed_drawtext_0 @ 000001e68fd95dc0] [FILE @ 0000009fb7ffee70] Error occurred in CreateFileMapping()
Error: [Parsed_drawtext_0 @ 000001e68fd95dc0] The text file 'OverlayFiles/OverlayFile_MyPC.txt' could not be read or is empty
Error: [vf#0:0 @ 000001e68fd48300] Error while filtering: Operation not permitted
Error: [vf#0:0 @ 000001e68fd48300] Task finished with error code: -1 (Operation not permitted)
Error message received from ffmpeg with the use of a temp file that's replacing the original file:
Error: [Parsed_drawtext_0 @ 0000014c815e6200] [FILE @ 000000253d7fee70] Cannot read file 'OverlayFiles/OverlayFile_MyPC.txt': Permission denied
Error: [Parsed_drawtext_0 @ 0000014c815e6200] The text file 'OverlayFiles/OverlayFile_MyPC.txt' could not be read or is empty
Error: [vf#0:0 @ 0000014c81597280] Error while filtering: Permission denied
Error: [vf#0:0 @ 0000014c81597280] Task finished with error code: -13 (Permission denied)
Error: [vf#0:0 @ 0000014c81597280] Terminating thread with return code -13 (Permission denied)
ffmpeg arguments:
string arguments = $"-video_size 1920x1080 -framerate 30 -f gdigrab -i desktop -c:v libx264rgb -crf 0 -preset ultrafast -color_range 2 " +
$"-vf \"drawtext=fontfile=C\\\\:/Windows/fonts/consola.ttf:fontsize=30:fontcolor='white':textfile={overlayFilePath_}:boxcolor=0x00000080:box=1:x=10:y=H-210:reload=1\" \"" +
outputFile + "\"";
The code that updates the overlay file (1st version):
public void UpdateOverlayText(string filePath)
{
string usage = GetSystemUsage(filePath); // Get the system usage data
try
{
// Open the file with FileShare.ReadWrite to allow other processes to read it while writing
using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
{
using (var writer = new StreamWriter(fileStream))
{
writer.Write(usage); // Write the system usage data to the file
}
}
// Ensure file permissions are set correctly after writing
SetFilePermissions(filePath);
}
catch (IOException ex)
{
Console.WriteLine($"Error updating overlay file: {ex.Message}");
}
}
(UPDATE)Code that updates overlay file using MemoryStream:
public void UpdateOverlayText(string filePath)
{
string usage = GetSystemUsage(filePath);
try
{
using (var memoryStream = new MemoryStream())
{
using (var writer = new StreamWriter(memoryStream))
{
writer.Write(usage);
writer.Flush();
memoryStream.Position = 0;
File.WriteAllBytes(filePath, memoryStream.ToArray());
}
}
SetFilePermissions(filePath);
}
catch (IOException ex)
{
Console.WriteLine($"Error updating overlay file: {ex.Message}");
}
}
Code tested using MemoryStream and Temp file:
public void UpdateOverlayText(string filePath)
{
string usage = GetSystemUsage(filePath);
string tempFilePath = filePath + ".tmp";
try
{
// Write to a temporary file first
using (var memoryStream = new MemoryStream())
{
using (var writer = new StreamWriter(memoryStream))
{
writer.Write(usage);
writer.Flush();
memoryStream.Position = 0;
File.WriteAllBytes(tempFilePath, memoryStream.ToArray());
}
}
File.Replace(tempFilePath, filePath, null);
}
catch (IOException ex)
{
Console.WriteLine($"Error updating overlay file: {ex.Message}");
}
finally
{
if (File.Exists(tempFilePath))
{
File.Delete(tempFilePath);
}
}
}
Thanks in advance for your help and sorry for any typo or wrong phrases I used.
Upvotes: 0
Views: 35