Write Failure on sending video to youtube flash player - c#

I'm having a problem with a youtube cache I'm trying to make (my internet connection is really slow). It works by detecting if a videoplayback page is requested and saves the response to the disk. It works fine with lightspark and the html5 player on FireFox, but when I try it on Google Chrome I get a Write Failure in RespCacheCallback.
I have the source here as it is too long to be posted with the question.

I forgot to add the range to the ID created in the program when I searched the cache, which meant that the program tried to send the entire video when a small portion was requested, which made the player close the connection. That was fixed by adding this method to MainClass
static bool TryGetRange (string url, out string range)
{
int index = url.IndexOf ("&range=");
if (index == -1) {
range = null;
return false;
}
index += 7;
int len = url.IndexOf ('&',index) - index;
range = url.Substring (index,len);
return true;
}
This method checks if the range parameter is present in the url, and then gets the value of it.
Then adding this code before if(File.Exists (requestData.Signature + "_done"))
string range;
if(TryGetRange (requestString, out range))
{
requestData.Signature += range;
}
This adds the range to the signature if the range parameter is detected

Related

"The process cannot access the file because it is being used by another process." with SystemReader

I have no coding experience but have been trying to fix a broken program many years ago. I've been fumbling through fixing things but have stumbled upon a piece that I can't fix. From what I've gathered you get Alexa to append a Dropbox file and the program reads that file looking for the change and, depending on what it is, executes a certain command based on a customizable list in an XML document.
I've gotten this to work about five times in the hundred of attempts I've done, every other time it will crash and Visual Studio gives me: "System.IO.IOException: 'The process cannot access the file 'C:\Users\\"User"\Dropbox\controlcomputer\controlfile.txt' because it is being used by another process.'"
This is the file that Dropbox appends and this only happens when I append the file, otherwise, the program works fine and I can navigate it.
I believe this is the code that handles this as this is the only mention of StreamReader in all of the code:
public static void launchTaskControlFile(string path)
{
int num = 0;
StreamReader streamReader = new StreamReader(path);
string str = "";
while (true)
{
string str1 = streamReader.ReadLine();
string str2 = str1;
if (str1 == null)
{
break;
}
str = str2.TrimStart(new char[] { '#' });
num++;
}
streamReader.Close();
if (str.Contains("Google"))
{
MainWindow.googleSearch(str);
}
else if (str.Contains("LockDown") && Settings.Default.lockdownEnabled)
{
MainWindow.executeLock();
}
else if (str.Contains("Shutdown") && Settings.Default.shutdownEnabled)
{
MainWindow.executeShutdown();
}
else if (str.Contains("Restart") && Settings.Default.restartEnabled)
{
MainWindow.executeRestart();
}
else if (!str.Contains("Password"))
{
MainWindow.launchApplication(str);
}
else
{
SendKeys.SendWait(" ");
Thread.Sleep(500);
string str3 = "potato";
for (int i = 0; i < str3.Length; i++)
{
SendKeys.SendWait(str3[i].ToString());
}
}
Console.ReadLine();
}
I've searched online but have no idea how I could apply anything I've found to this. Once again before working on this I have no coding experience so act like you're talking to a toddler.
Sorry if anything I added here is unnecessary I'm just trying to be thorough. Any help would be appreciated.
I set up a try delay pattern like Adriano Repetti said and it seems to be working, however doing that flat out would only cause it to not crash so I had to add a loop around it and set the loop to stop when a variable hit 1, which happened whenever any command types are triggered. This takes it out of the loop and sets the integer back to 0, triggering the loop again. That seems to be working now.

Does UnityWebRequest.uploadProgress have side effects?

I have the following upload code using Unity's UnityWebRequest API (Unity 2019.2.13f1):
public IEnumerator UploadJobFile(string jobId, string path)
{
if (!File.Exists(path))
{
Debug.LogError("The given file to upload does not exist. Please re-create the recording and try again.");
yield break;
}
UnityWebRequest upload = new UnityWebRequest(hostURL + "/jobs/upload/" + jobId);
upload.uploadHandler = new UploadHandlerFile(path);
upload.downloadHandler = new DownloadHandlerBuffer();
upload.method = UnityWebRequest.kHttpVerbPOST;
upload.SetRequestHeader("filename", Path.GetFileName(path));
UnityWebRequestAsyncOperation op = upload.SendWebRequest();
while (!upload.isDone)
{
//Debug.Log("Uploading file...");
Debug.Log("Uploading file. Progress " + (int)(upload.uploadProgress * 100f) + "%"); // <-----------------
yield return null;
}
if (upload.isNetworkError || upload.isHttpError)
{
Debug.LogError("Upload error:\n" + upload.error);
}
else
{
Debug.Log("Upload success");
}
// this is needed to clear resources on the file
upload.Dispose();
}
string hostURL = "http://localhost:8080";
string jobId = "manualUploadTest";
string path = "E:/Videos/short.mp4";
void Update()
{
if (Input.GetKeyDown(KeyCode.O))
{
Debug.Log("O key was pressed.");
StartCoroutine(UploadAndTest(jobId, path));
}
}
And the files I receive on the server side arrive broken, especially if they are larger (30 MB or more). They are missing bytes in the end and sometimes have entire byte blocks duplicated in the middle.
This happens both when testing client and server on the same machine or when running on different machines.
The server does not complain - from its perspective, no transport errors happened.
I noticed that if I comment out the access to upload.uploadProgress (and e.g. instead use the commented-out debug line above it which just prints a string literal), the files stay intact. Ditching the wile loop altogether and replacing it with yield return op also works.
I tested this strange behavior repeatedly in an outer loop - usually after at most 8 repetitions with the "faulty" code, the file appears broken. If I use the "correct" variant, 100 uploads (update: 500) in a row were successful.
Has upload.uploadProgress side-effects? For what it's worth, the same happens if I print op.progress instead - the files are also broken.
This sounds like a real bug. uploadProgress obviously should not have side effects.

Saving a variable that gets loaded on program startup (WFA) C#

The user is asked to type in the serial number on the device he's using. Then the program uses this serial number for all the functions. This was made so that the user can easily replace said device, without any technical help - just typing the new serial number in the application.
However, the way I've done it, the user needs to type in the serial number each time the program is opened, and it's kind of tedious.
Is there a way to store the last entered serial number, so that it loads the next time the program is being runned?
I have checked this link. While it seems promising, it hasn't solved the problem for me. I'll explain with my code below.
Here is the code asking for the user input serial number:
byte[] xbee { get; set; }
var xbee_serienr = prop1_serienr.Text;
xbee = new byte[xbee_serienr.Length / 2];
for (var i = 0; i < xbee.Length; i++)
{
xbee[i] = byte.Parse(xbee_serienr.Substring(i * 2, 2), NumberStyles.HexNumber);
}
I tried the aforementioned link, and save it like so:
prop1_serienr string user 0013A20040A65E23
And then use it in the code like so:
prop1_serienr = Xbee.Properties.Settings.Default.prop1_serienr;
//keep in mind I made the silly decision using Xbee as namespace and xbee as a variable
But the prop1_serienr remains empty this way.
Any tips or guidelines on how to make this easier than having to type it every time the program starts would be greatly appreciated. If that's my only option I will resort to hard coding the serial numbers and then change the code every time a device is changed.
Hard coding the serial numbers is really not an option, especially when something as "saving a serial number" is not very complicated at all (but like all things, complicated it can be, if you let it).
The very easy approach:
public partial class Form1 : Form
{
private byte[] _xbee;
public Form1()
{
if (!File.Exists("serial.txt"))
{
File.Create("serial.txt");
}
else
{
_xbee = File.ReadAllBytes("serial.txt");
}
InitializeComponent();
}
private void btnSaveSerial_Click(object sender, EventArgs e)
{
byte[] xbee { get; set; }
var xbee_serienr = prop1_serienr.Text;
xbee = new byte[xbee_serienr.Length / 2];
for (var i = 0; i < xbee.Length; i++)
{
xbee[i] = byte.Parse(xbee_serienr.Substring(i * 2, 2), NumberStyles.HexNumber);
}
_xbee = xbee;
File.WriteAllBytes("serial.txt", xbee);
}
}
It reads the bytes from the file at startup (if the file exists).
It writes the bytes to the file when the user has changed the serial (and clicked on a button to save it).
As I've said, you can make this as easy or as complicated as you like, but this should get you going.

How to better implement start and stop video recording Web Services using Axis Media Parser API?

I have a C# Web Service which records data from an IP camera. This service works fine when I record data during a specified amount of time, for example 10 seconds. But my objective is to achieve data recording for an unspecified amount of time and let the user press to stop recording. So I modified my code creating a new Web Service (stopRecording) to change the value of a global variable that acts as a mutex. Obviously this is wrong because I test it but I don´t know how to proceed. Can anybody help me? I would really appreciate it.
Down here I leave the relevant code.
[WebMethod]
public string startRecording(string ipAddress)
{
// Connection preset for H.264 (HTTP API 3.0)
string Url = "axrtsp:://" + ipAddress + "/axis-media/media.amp?videocodec=h264";
string UserName = "username";
string Password = "pass";
string Path = "C:/directory/subdirectory/";
string Filename = "myRecordedFile.bin";
string FilePath = Path + Filename;
// Open binary output file to write parsed video frames into
using (FileStream outFileStream = new FileStream(FilePath, FileMode.Create))
using (outFile = new BinaryWriter(outFileStream))
{
try
{
// Register for events like OnVideoSample, OnAudioSample, OnTriggerData and OnError
...
// Set connection and media properties
...
// Get absolute time from Axis device
...
// Connect to the device
int cookieID;
int numberOfStreams;
object buffer;
parser.Connect(out cookieID, out numberOfStreams, out buffer);
// Write media type information to out file (buffer is an array of bytes)
byte[] mediaTypeBuffer = (byte[])buffer;
outFile.Write(mediaTypeBuffer.Length);
outFile.Write(mediaTypeBuffer, 0, mediaTypeBuffer.Length);
// Start the media stream and registered event handlers will be called
parser.Start();
Debug.WriteLine("Will start recording...");
do {
Debug.WriteLine("recording..."); //want to record during an unspecified time
} while (record); //my mutex variable that doesn´t make the thing even when I call the stopRecording Web Service. The program remains overlooping
System.Diagnostics.Debug.Write("Finish recording... never reached!!!!! ");
// Stop the stream
parser.Stop();
// Unregister event handlers
...
}
catch (COMException e)
{
Console.WriteLine("Exception for {0}, {1}", parser.MediaURL, e.Message);
}
// Inform the GC that COM object no longer will be used
Marshal.FinalReleaseComObject(parser);
parser = null;
Console.WriteLine("Stream stopped");
}
return "Recording from camera " + Url;
}
[WebMethod]
public string stopRecording()
{
System.Diagnostics.Debug.Write("I want to stop recording...");
record = false;
return "Stop";
}
Your record variable is not a Mutex object, but a simple flag... Which is besides the point.
Trouble here is that you code in startRecording() never gives the hand back to the parent class and might be holding the processing thread forever.
If I might suggest, why not create a thread to do your recording ? You have a number of possibilities here ( new Thread(), Action.BeginInvoke(), .. )
This way, you give a chance to your stopRecording to be received and set this record flag to false and leave the recording thread.

Xamarin Monotouch Audio Units Callbacks

I have a problem with Audio Units in MonoTouch/Xamarin.
It seems like I can't get a callback on recording, just playback.
I used this example:
https://github.com/xamarin/monotouch-samples/blob/master/AUSoundTriggeredPlayingSoundMemoryBased/ExtAudioBufferPlayer.cs
and looked for Obj C examples. The Obj C examples are pretty much the same like my code so Im a little bit confused about this thing.
The output if running my example is:
INPUT0
Which is the bus number for output.
So the expected output should be:
INPUT1
So my question is: How do I get a recording callback and a playback callback running the same time, or just how do I get a recording callback.
My Code:
void prepareAudioUnit()
{
// AudioSession
AudioSession.Initialize();
AudioSession.Category = AudioSessionCategory.PlayAndRecord;
AudioSession.PreferredHardwareIOBufferDuration = Config.packetLength;
AudioSession.PreferredHardwareSampleRate = Format.samplingRate;
//AudioSession.SetActive (false);
AudioSession.SetActive(true);
Logger.log("HWSR:" + AudioSession.CurrentHardwareSampleRate);
// Getting AudioComponent Remote output
_audioComponent = AudioComponent.FindComponent(AudioTypeOutput.VoiceProcessingIO);
// creating an audio unit instanc
_audioUnit = new AudioUnit(_audioComponent);
// turning on microphone
_audioUnit.SetEnableIO(true,
AudioUnitScopeType.Input,
1 // Remote Input
);
_audioUnit.SetEnableIO(true,
AudioUnitScopeType.Output,
0 // Remote output
);
// setting audio format
_audioUnit.SetAudioFormat(Format.AudioStreamBasicDescription,
AudioUnitScopeType.Output,
1
);
_audioUnit.SetAudioFormat(Format.AudioStreamBasicDescription,
AudioUnitScopeType.Input,
0
);
// setting callback method
_audioUnit.SetRenderCallback(_audioUnit_OutputCallback, AudioUnitScopeType.Global, 0);
_audioUnit.SetRenderCallback(_audioUnit_InputCallback, AudioUnitScopeType.Global, 1);
}
AudioUnitStatus _audioUnit_OutputCallback(AudioUnitRenderActionFlags actionFlags, AudioTimeStamp timeStamp, uint busNumber, uint numberFrames, AudioBuffers data)
{
Logger.log("OUTPUT" + busNumber);
return AudioUnitStatus.NoError;
}
AudioUnitStatus _audioUnit_InputCallback(AudioUnitRenderActionFlags actionFlags, AudioTimeStamp timeStamp, uint busNumber, uint numberFrames, AudioBuffers data)
{
Logger.log("INPUT" + busNumber);
return AudioUnitStatus.NoError;
}
This problem is a bug in Xamarin, they forgot to add a method for InputCallbacks.
I reported the bug but for the people needing the same:
http://nopaste.info/8d0aca98d9.html
Its not good, but it shows how to solve the problem to write a fix yourself till Xamarin updates this.

Categories

Resources