I'm working on a project to make sure that users finish a video. I would like to have it just add something like "user has finished video" to an already existing text file.
Here is what I have in my JavaScript file.
var video = document.getElementById("video");
var timeStarted = -1;
var timePlayed = 0;
var duration = 0;
// If video metadata is laoded get duration
if (video.readyState > 0)
getDuration.call(video);
//If metadata not loaded, use event to get it
else {
video.addEventListener('loadedmetadata', getDuration);
}
// remember time user started the video
function videoStartedPlaying() {
timeStarted = new Date().getTime() / 1000;
}
function videoStoppedPlaying(event) {
// Start time less then zero means stop event was fired vidout start event
if (timeStarted > 0) {
var playedFor = new Date().getTime() / 1000 - timeStarted;
timeStarted = -1;
// add the new ammount of seconds played
timePlayed += playedFor;
}
document.getElementById("played").innerHTML = Math.round(timePlayed) + "";
// Count as complete only if end of video was reached
if (timePlayed >= duration && event.type == "ended") {
document.getElementById("status").className = "complete";
}
}
function getDuration() {
duration = video.duration;
document.getElementById("duration").appendChild(new Text(Math.round(duration) + ""));
console.log("Duration: ", duration);
}
video.addEventListener("play", videoStartedPlaying);
video.addEventListener("playing", videoStartedPlaying);
video.addEventListener("ended", videoStoppedPlaying);
video.addEventListener("pause", videoStoppedPlaying);
var data = "This user has finished the video";
var url = "data.php";
var http = new XMLHttpRequest();
http.open("POST", url, true);
//sends hearder info along with the request
http.setRequestHeader("content-type", "application/x-www-form-urlencoded");
http.onreadystatechange = function() {
if (http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(data);
and Data.php has
<?php
$data = $_POST['data'];
$file = fopen('names.txt', 'a');
fwrite($file, $data);
fclose($file);
?>
As of now, there are no errors in the console, but it does not write the data to the text file.
Please let me know what i'm doing wrong
Since you are using http.setRequestHeader("content-type", "application/x-www-form-urlencoded");, the request expects the data to be formatted like serialized HTML form data. Change the following line to provide the data in the proper format:
var data = "data=This%20user%20has%20finished%20the%20video";
Related
I get the src code for image from PHP and after show at the HTML but the images are shown with a delay. How can I show the images all together without reordering after all loaded?
HTML
<div id="keys"></div>
JS
function sendGETDataToServer() {
// Set up our HTTP request
var xhr = new XMLHttpRequest();
// Setup our listener to process completed requests
xhr.onreadystatechange = function () {
// Only run if the request is complete
if (xhr.readyState !== 4) return;
// Process our return data
if (xhr.status >= 200 && xhr.status < 300) {
var JsonResponse = xhr.responseText;
var response = JSON.parse(JsonResponse);
console.log(response);
if (response[0] == "200 OK") {
var i;
for (i = 0; i < response[1]; i++) {
let img = document.createElement("img");
img.src = response[2 + i].FilePath;
img.setAttribute("style", "width:8%; padding-left:1em; float:left");
$("#keys").append(img);
}
}
} else {
console.log("error", xhr);
}
};
xhr.open("GET", "load.php");
xhr.send();
}
Your code should look like something like that
if (response[0] == '200 OK') {
var i;
var nbLoaded = 0;
var nbToLoad = 0;
var pendingImages = [];
for (i = 0; i < response[1]; i++) {
nbToLoad++;
let img = document.createElement('img');
img.src = response[2 + i].FilePath;
img.setAttribute('style', 'width:8%; padding-left:1em; float:left');
img.onload = () => {
nbLoaded++;
if (nbLoaded === nbToLoad) {
pendingImages.forEach((image) => {
$('#keys').append(image);
});
}
};
pendingImages.push(img);
}
}
The short answer to your problem: There isn't really one. There is not a way to know what order your images will arrive in, and you certainly cannot control the delay. What you can control is the order you show them in. The simplest way to do this is to wait until you have received all of your images, and while you are receiveing them, you store them in an array somewhere. After you receive the final image, you could simply order the array the way you want your images to be displayed, and run through it to actually put the images on the page. If you need any help with the specifics, please feel free to ask!
I have a script giving me error 403 Forbidden error.
When i run this script on server getting status code 403 forbidden error in Console
means the script are stop in this line
xmlhttp.open("POST", 'process_thumb.php', true);
This is my Script
<script type="text/javascript">
var index = 0;
var video = document.getElementById('video');
var starttime = 0.00; // start at 7 seconds
var endtime = 0.00; // stop at 17 seconds
video.addEventListener("timeupdate", function () {
if (this.currentTime >= endtime) {
this.pause();
getThumb();
}
}, false);
video.play();
video.currentTime = starttime;
function getThumb() {
var filename = video.src;
var w = video.videoWidth;//video.videoWidth * scaleFactor;
var h = video.videoHeight;//video.videoHeight * scaleFactor;
var canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
var ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, w, h);
//document.body.appendChild(canvas);
var data = canvas.toDataURL("image/jpg");
//send to php script
var xmlhttp = new XMLHttpRequest;
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
console.log('saved');
}
}
console.log('saving');
xmlhttp.open("POST", 'process_thumb.php', true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send('name=' + encodeURIComponent(filename) + '&data=' + data);
xmlhttp.onreadystatechange = function () {//Call a function when the state changes.
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
//alert(xmlhttp.responseText==1);
if (xmlhttp.responseText == 1)
{
// window.location = 'video.php';
} else
{
alert('Please Try Again');
window.location = 'add-video.php';
}
}
}
}
function failed(e) {
// video playback failed - show a message saying why
switch (e.target.error.code) {
case e.target.error.MEDIA_ERR_ABORTED:
console.log('You aborted the video playback.');
break;
case e.target.error.MEDIA_ERR_NETWORK:
console.log('A network error caused the video download to fail part-way.');
break;
case e.target.error.MEDIA_ERR_DECODE:
console.log('The video playback was aborted due to a corruption problem or because the video used features your browser did not support.');
break;
case e.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
console.log('The video could not be loaded, either because the server or network failed or because the format is not supported.');
break;
default:
console.log('An unknown error occurred.');
break;
}
}
</script>
process_thumb.php
$thumbs_dir="images/thumbnail/";
if (isset($_POST["name"]) && $_POST["name"]) {
// Grab the MIME type and the data with a regex for convenience
if (!preg_match('/data:([^;]*);base64,(.*)/', $_POST['data'], $matches)) {
die("error");
}
$file = basename($_POST['name'], '.mp4');
// Decode the data
$data = $matches[2];
$data = str_replace(' ', '+', $data);
$data = base64_decode($data);
file_put_contents($thumbs_dir . $file . ".jpg", $data);
Any solution here ?
Thanks
My file.js is calling a php file to fetch from database and return an encoded JSON object so I can put it on a table. Here is the file.js -
url = "backend.php"
xmlhttp.open("GET", url, true);
xmlhttp.send();
xmlhttp.onreadystatechange = function()
{
if (this.readyState == 4 && this.status == 200)
{
myJSONObj = JSON.parse(this.responseText);
for ( i=0;i<myJSON.length;i++)
{
var x = document.getElementById("datatable").rows[i].cells;
x[6].innerHTML =obj[i].age;
}
}
}
And the backend.php file goes -
$sql_stmt= "SELECT * FROM TABLE ";
$result = odbc_exec($conn_id, $sql_stmt);
while ($row = odbc_fetch_array($result)) {
$age=$row['age'];
$ages[] = array('age'=> $age);
}
$myJSON = json_encode($ages);
echo $myJSON;
This works completely fine, but I have to wait for the PHP while loop to finish, which takes too long with large number of entries. I want to be able to return the JSON within the loop, not at the end.
Is there any way I can make the xmlhttp request and keep receiving JSON while the PHP while loop runs, not having to wait for it to finish and then send across all the rows together? Thanks
I think you should use mysql limit
JS:
var hasData = true;
var loop = 0;
while(hasData){
url = "backend.php?page="+loop;
xmlhttp.open("GET", url, true);
xmlhttp.send();
xmlhttp.onreadystatechange = function()
{
if (this.readyState == 4 && this.status == 200)
{
if(this.reponseText != ""){
myJSONObj = JSON.parse(this.responseText);
for ( i=0;i<myJSON.length;i++)
{
var x = document.getElementById("datatable").rows[i].cells;
x[6].innerHTML =obj[i].age;
}
}else{
hasData = false; //if no data retrieved
}//end if
}//end if
}
loop++; //increment loop
}//end while
PHP:
$loop = $_GET['loop'];
if($loop != ""){
$max_output = 10; //how many rows you want to display per query
$starting_row = $max_output * $loop;
// LIMIT 0, 10 = if loop is 0
// LIMIT 10, 10 = if loop is 1
// LIMIT 20, 10 = if loop is 2
$sql_stmt= "SELECT * FROM TABLE LIMIT {$starting_row}, {$max_output}";
$result = odbc_exec($conn_id, $sql_stmt);
if($result){
while ($row = odbc_fetch_array($result)) {
$age=$row['age'];
$ages[] = array('age'=> $age);
}
$myJSON = json_encode($ages);
echo $myJSON;
}else{
exit; //make sure nothing is echoed/print
}
}
{
myJSONObj = JSON.parse(this.responseText);
for ( i=0;i<myJSON.length;i++)
{
var x = document.getElementById("datatable").rows[i].cells;
x[6].innerHTML =obj[i].age;
}
}
}
Hope this helps
Since my main language is C, I am used to pointers and I love them. Now I have some project which I need to finish in Javascript and I've got a problem which I don't know how to solve.
I want to store the value of a variable which I got from GET request. I have a script to send GET to PHP page, which then sends GET to my daemon written in C. When I get the string I wanted, I use length to measure the size of the string I got and in next GET request I want to send that number of bytes I got as the URL parameter.
window.onload = function() {
if (bytes === undefined) {
var bytes = 0;
}
var url = "/test/log.php?q=" + bytes;
function httpGet(url) {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", url, true);
xhttp.onload = function(e) {
if (xhttp.readyState === 4) {
if (xhttp.status === 200) {
console.log(xhttp.responseText);
var option = "";
obj = JSON.parse(xhttp.responseText);
for (var key in obj) {
option += obj[key];
}
document.getElementById("list").innerHTML = asdf;
bytes = option.length;
}
};
xhttp.onerror = function(e) {
console.error(xhttp.statusText);
}
};
xhttp.send();
}
var updateInterval = 2000;
function update() {
httpGet(url);
setTimeout(update, updateInterval);
}
update();
}
So, the focus is on the variable bytes. It should have the value 0 when the script is a first time called, and after every loop (it loops every 2 seconds, I didn't show the loop in the code) it should have the value of the previous length of received string.
You just need to make sure to add the bytes param onto your url in a way that changes with each call rather than just once at page load when it will always be 0.
window.onload = function() {
if (bytes === undefined) {
var bytes = 0;
}
var url = "/test/log.php?q=";
function httpGet(url) {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", url, true);
xhttp.onload = function(e) {
if (xhttp.readyState === 4) {
if (xhttp.status === 200) {
console.log(xhttp.responseText);
var option = "";
obj = JSON.parse(xhttp.responseText);
for (var key in obj) {
option += obj[key];
}
document.getElementById("list").innerHTML = asdf;
bytes = option.length;
}
};
xhttp.onerror = function(e) {
console.error(xhttp.statusText);
}
};
xhttp.send();
}
var updateInterval = 2000;
function update() {
httpGet(url + bytes);
setTimeout(update, updateInterval);
}
update();
}
Instead of a fixed value of url make it to a function and it will give you always the current Url with the modified version of bytes, if you modify it
You have only to change this parts
var url = ...
// to
function getUrl() {
return "/test/log.php?q=" + bytes;
}
...
// and
xhttp.open("GET", url, true);
// to
xhttp.open("GET", getUrl(), true);
I'd declare the variable in a context that doesn't empty its value when the function is called. So, you can declare your variable "bytes" before the function, and then looping through that function. In this case, the variable will hold the last value until you overwrite it.
That should work!
How to populate the select list with the values that I got with javascript?
I am sending a GET request to a .php site which gives me the respond in JSON format. Now I want to put those lines I got into the select list.
<select id = "list" name=log size=50 style=width:1028px>
<script type="text/javascript">
window.onload = function () {
var bytes=0;
var url = "/test/log.php?q='0'";
function httpGet(url)
{
var xhttp = new XMLHttpRequest();
var realurl = url + bytes;
xhttp.open("GET", url, true);
xhttp.onload = function (e) {
if (xhttp.readyState === 4) {
if (xhttp.status === 200) {
console.log(xhttp.responseText);
var response=JSON.parse(xhttp.responseText);
var log = response.key;
bytes = log.length;
}
};
xhttp.onerror = function (e) {
console.error(xhttp.statusText);
}
};
xhttp.send();
}
var updateInterval = 2000;
function update() {
httpGet(url);
setTimeout(update, updateInterval);
}
update();
}
</script>
</select>
The response I get from log.php is "{"key":"whole log file"}". Now I want to store that reponse into a list and populate it every 2 seconds.
Loop over the contents of the returned string after JSON.parse-ing it. Create option elements from it, and insert those into the select.
var html = "";
var obj = JSON.parse(xhttp.responseText);
for(var key in obj) {
html += "<option value=" + key + ">" +obj[key] + "</option>";
}
document.getElementById("list").innerHTML = html;
See JSBin