为什么程序写入空套接字?
Why The Program Writes To Socket Empty?
我正在制作一个记录视频的程序,并每隔 5 次将其 blob 发送到一个套接字 secs.It 似乎工作正常但是当我查看服务器接收的文件时,我看到了由socket client are empty= 0kb.Can 你帮帮我好吗?我的 HTML/JS 和 PHP 代码如下。
<!DOCTYPE html>
<html lang="en">
<head>
<title>WebRTC Video Recording using MediaStreamRecorder</title>
<script src="https://cdn.WebRTC-Experiment.com/MediaStreamRecorder.js"></script>
<!-- for Edige/FF/Chrome/Opera/etc. getUserMedia support -->
<script src="https://cdn.WebRTC-Experiment.com/gumadapter.js"></script>
<link rel="stylesheet" href="https://cdn.webrtc-experiment.com/style.css">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<link rel="author" type="text/html" href="https://plus.google.com/+MuazKhan">
<meta name="author" content="Muaz Khan">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<style>
input {
border: 1px solid rgb(46, 189, 235);
border-radius: 3px;
font-size: 1em;
outline: none;
padding: .2em .4em;
width: 60px;
text-align: center;
}
select {
vertical-align: middle;
line-height: 1;
padding: 2px 5px;
height: auto;
font-size: inherit;
margin: 0;
}
</style>
</head>
<body>
<article>
<header style="text-align: center;">
<h1>
<a href="https://www.webrtc-experiment.com/">WebRTC</a> Video Recording using <a href="https://github.com/streamproc/MediaStreamRecorder" target="_blank">MediaStreamRecorder</a>
</h1>
<p>
<a href="https://www.webrtc-experiment.com/">HOME</a>
<span> © </span>
<a href="https://www.webrtc-experiment.com/">WebRTC Experiment</a> .
</p>
</header>
<section class="experiment" style="padding: 5px;">
<label for="time-interval">Time Interval (milliseconds):</label>
<input type="text" id="time-interval" value="5000">
<br>
<br> recorderType:
<select id="video-recorderType" style="font-size:22px;vertical-align: middle;margin-right: 5px;">
<option value="[Best Available Recorder]">[Best Available Recorder]</option>
<option value="MediaRecorder API">MediaRecorder API</option>
<option value="WebP encoding into WebM">WebP encoding into WebM</option>
</select>
<br>
<br>
<button id="start-recording">Start</button>
<button id="stop-recording" disabled>Stop</button>
<button id="pause-recording" disabled>Pause</button>
<button id="resume-recording" disabled>Resume</button>
<button id="save-recording" disabled>Save</button>
<br>
<br>
<label for="video-width">Video Width:</label>
<input type="text" id="video-width" value="320">
<label for="video-height">Video Height:</label>
<input type="text" id="video-height" value="240">
</section>
<section class="experiment">
<div id="videos-container">
</div>
</section>
<script>
function captureUserMedia(mediaConstraints, successCallback, errorCallback) {
navigator.mediaDevices.getUserMedia(mediaConstraints).then(successCallback).catch(errorCallback);
}
var mediaConstraints = {
audio: !IsOpera && !IsEdge, // record both audio/video in Firefox/Chrome
video: true
};
document.querySelector('#start-recording').onclick = function() {
this.disabled = true;
captureUserMedia(mediaConstraints, onMediaSuccess, onMediaError);
};
document.querySelector('#stop-recording').onclick = function() {
this.disabled = true;
mediaRecorder.stop();
mediaRecorder.stream.stop();
document.querySelector('#pause-recording').disabled = true;
document.querySelector('#start-recording').disabled = false;
};
document.querySelector('#pause-recording').onclick = function() {
this.disabled = true;
mediaRecorder.pause();
document.querySelector('#resume-recording').disabled = false;
};
document.querySelector('#resume-recording').onclick = function() {
this.disabled = true;
mediaRecorder.resume();
document.querySelector('#pause-recording').disabled = false;
};
document.querySelector('#save-recording').onclick = function() {
this.disabled = true;
mediaRecorder.save();
// alert('Drop WebM file on Chrome or Firefox. Both can play entire file. VLC player or other players may not work.');
};
var mediaRecorder;
function onMediaSuccess(stream) {
var video = document.createElement('video');
var videoWidth = document.getElementById('video-width').value || 320;
var videoHeight = document.getElementById('video-height').value || 240;
video = mergeProps(video, {
controls: true,
muted: true,
width: videoWidth,
height: videoHeight,
src: URL.createObjectURL(stream)
});
video.play();
videosContainer.appendChild(video);
videosContainer.appendChild(document.createElement('hr'));
mediaRecorder = new MediaStreamRecorder(stream);
mediaRecorder.stream = stream;
var recorderType = document.getElementById('video-recorderType').value;
if (recorderType === 'MediaRecorder API') {
mediaRecorder.recorderType = MediaRecorderWrapper;
}
if (recorderType === 'WebP encoding into WebM') {
mediaRecorder.recorderType = WhammyRecorder;
}
// don't force any mimeType; use above "recorderType" instead.
// mediaRecorder.mimeType = 'video/webm'; // video/webm or video/mp4
mediaRecorder.videoWidth = videoWidth;
mediaRecorder.videoHeight = videoHeight;
mediaRecorder.ondataavailable = function(blob) {
var a = document.createElement('a');
a.target = '_blank';
a.innerHTML = 'Open Recorded Video No. ' + (index++) + ' (Size: ' + bytesToSize(blob.size) + ') Time Length: ' + getTimeLength(timeInterval);
a.href = URL.createObjectURL(blob);
videosContainer.appendChild(a);
videosContainer.appendChild(document.createElement('hr'));
// EKLENEN
var myRequest = new XMLHttpRequest();
myRequest.open('POST', 'save.php' , true);
myRequest.send(blob);
};
var timeInterval = document.querySelector('#time-interval').value;
if (timeInterval) timeInterval = parseInt(timeInterval);
else timeInterval = 5 * 1000;
// get blob after specific time interval
mediaRecorder.start(timeInterval);
document.querySelector('#stop-recording').disabled = false;
document.querySelector('#pause-recording').disabled = false;
document.querySelector('#save-recording').disabled = false;
}
function onMediaError(e) {
console.error('media error', e);
}
var videosContainer = document.getElementById('videos-container');
var index = 1;
function bytesToSize(bytes) {
var k = 1000;
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes === 0) return '0 Bytes';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(k)), 10);
return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
}
function getTimeLength(milliseconds) {
var data = new Date(milliseconds);
return data.getUTCHours() + " hours, " + data.getUTCMinutes() + " minutes and " + data.getUTCSeconds() + " second(s)";
}
window.onbeforeunload = function() {
document.querySelector('#start-recording').disabled = false;
};
</script>
<pre style="border-left: 2px solid red; margin-left:2em; padding-left: 1em;">
// cdn.webrtc-experiment.com/MediaStreamRecorder.js
var mediaConstraints = {
audio: true,
video: true // if firefox or chrome
};
navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError);
function onMediaSuccess(stream) {
var mediaRecorder = new MediaStreamRecorder(stream);
mediaRecorder.mimeType = 'video/webm';
mediaRecorder.ondataavailable = function (blob) {
// POST/PUT "Blob" using FormData/XHR2
var blobURL = URL.createObjectURL(blob);
document.write('<a href="' + blobURL + '">' + blobURL + '</a>');
};
mediaRecorder.start(3000);
}
function onMediaError(e) {
console.error('media error', e);
}
</pre>
<a href="https://www.webrtc-experiment.com/msr/" style="border-bottom: 1px solid red; color: red; font-size: 1.2em; position: absolute; right: 0; text-decoration: none; top: 0;">MediaStreamRecorder Demos</a>
<script>
window.useThisGithubPath = 'streamproc/MediaStreamRecorder';
</script>
<script src="https://cdn.webrtc-experiment.com/commits.js" async></script>
</article>
<footer>
<a href="https://www.webrtc-experiment.com/licence/">MIT License</a>
<table>
<tr> <td>
</td>
</tr>
</p>
</footer>
</body>
</html>
和PHP下面的套接字客户端:
<?php
$portnum = 'portnum';
$ipnum = 'Ipnum';
// No Timeout
set_time_limit(0);
if ( ($socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) == FALSE ) {
$message = "Socket not created";
echo "<script type='text/javascript'>alert('$message');</script>";
}
$context = stream_context_create($opts);
if ( ($file = file_get_contents($_FILES['blob'], false, $context ) ) == FALSE ) {
$message = "File_get_contents not working.";
echo "<script type='text/javascript'>alert('$message');</script>";
}
$ss = fopen ( file, "r");
$streamvid = fread ( $ss );
if ( ( $tt = fsockopen($ipnum, $portnum, $errno, $errstr, 30)) == FALSE ) {
$message = "fsockopen not working";
echo "<script type='text/javascript'>alert('$message');</script>";
}
if ( (fwrite ( $tt , $streamvid ) ) == FALSE ) { // DIŞARI ALINDI
$message = "fwrite failed";
echo "<script type='text/javascript'>alert('$message');</script>";
}
fclose( $tt );
?>
mediaRecorder.ondataavailable = function(blob) {
// upload blob to PHP server
uploadToPHPServer(blob);
};
function uploadToPHPServer(blob) {
var file = new File([blob], 'msr-' + (new Date).toISOString().replace(/:|\./g, '-') + '.webm', {
type: 'video/webm'
});
// create FormData
var formData = new FormData();
formData.append('video-filename', file.name);
formData.append('video-blob', file);
makeXMLHttpRequest('https://path-to-your-server/save.php', formData, function() {
var downloadURL = 'https://path-to-your-server/uploads/' + file.name;
console.log('File uploaded to this path:', downloadURL);
});
}
function makeXMLHttpRequest(url, data, callback) {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
callback();
}
};
request.open('POST', url);
request.send(data);
}
这里是save.php
:
<?php
// via: https://github.com/muaz-khan/RecordRTC/blob/master/RecordRTC-to-PHP/save.php
header("Access-Control-Allow-Origin: *");
function selfInvoker()
{
if (!isset($_POST['audio-filename']) && !isset($_POST['video-filename'])) {
echo 'PermissionDeniedError';
return;
}
$fileName = '';
$tempName = '';
if (isset($_POST['audio-filename'])) {
$fileName = $_POST['audio-filename'];
$tempName = $_FILES['audio-blob']['tmp_name'];
} else {
$fileName = $_POST['video-filename'];
$tempName = $_FILES['video-blob']['tmp_name'];
}
if (empty($fileName) || empty($tempName)) {
echo 'PermissionDeniedError';
return;
}
$filePath = 'uploads/' . $fileName;
// make sure that one can upload only allowed audio/video files
$allowed = array(
'webm',
'wav',
'mp4',
'mp3',
'ogg'
);
$extension = pathinfo($filePath, PATHINFO_EXTENSION);
if (!$extension || empty($extension) || !in_array($extension, $allowed)) {
echo 'PermissionDeniedError';
continue;
}
if (!move_uploaded_file($tempName, $filePath)) {
echo ('Problem saving file.');
return;
}
echo ($filePath);
}
selfInvoker();
?>
关于PHP上传问题,
PS。不要忘记在此处创建 uploads
目录:
- https://path-to-your-server/uploads/ ----- 在与 "save.php"
相同的目录中
我正在制作一个记录视频的程序,并每隔 5 次将其 blob 发送到一个套接字 secs.It 似乎工作正常但是当我查看服务器接收的文件时,我看到了由socket client are empty= 0kb.Can 你帮帮我好吗?我的 HTML/JS 和 PHP 代码如下。
<!DOCTYPE html>
<html lang="en">
<head>
<title>WebRTC Video Recording using MediaStreamRecorder</title>
<script src="https://cdn.WebRTC-Experiment.com/MediaStreamRecorder.js"></script>
<!-- for Edige/FF/Chrome/Opera/etc. getUserMedia support -->
<script src="https://cdn.WebRTC-Experiment.com/gumadapter.js"></script>
<link rel="stylesheet" href="https://cdn.webrtc-experiment.com/style.css">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<link rel="author" type="text/html" href="https://plus.google.com/+MuazKhan">
<meta name="author" content="Muaz Khan">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<style>
input {
border: 1px solid rgb(46, 189, 235);
border-radius: 3px;
font-size: 1em;
outline: none;
padding: .2em .4em;
width: 60px;
text-align: center;
}
select {
vertical-align: middle;
line-height: 1;
padding: 2px 5px;
height: auto;
font-size: inherit;
margin: 0;
}
</style>
</head>
<body>
<article>
<header style="text-align: center;">
<h1>
<a href="https://www.webrtc-experiment.com/">WebRTC</a> Video Recording using <a href="https://github.com/streamproc/MediaStreamRecorder" target="_blank">MediaStreamRecorder</a>
</h1>
<p>
<a href="https://www.webrtc-experiment.com/">HOME</a>
<span> © </span>
<a href="https://www.webrtc-experiment.com/">WebRTC Experiment</a> .
</p>
</header>
<section class="experiment" style="padding: 5px;">
<label for="time-interval">Time Interval (milliseconds):</label>
<input type="text" id="time-interval" value="5000">
<br>
<br> recorderType:
<select id="video-recorderType" style="font-size:22px;vertical-align: middle;margin-right: 5px;">
<option value="[Best Available Recorder]">[Best Available Recorder]</option>
<option value="MediaRecorder API">MediaRecorder API</option>
<option value="WebP encoding into WebM">WebP encoding into WebM</option>
</select>
<br>
<br>
<button id="start-recording">Start</button>
<button id="stop-recording" disabled>Stop</button>
<button id="pause-recording" disabled>Pause</button>
<button id="resume-recording" disabled>Resume</button>
<button id="save-recording" disabled>Save</button>
<br>
<br>
<label for="video-width">Video Width:</label>
<input type="text" id="video-width" value="320">
<label for="video-height">Video Height:</label>
<input type="text" id="video-height" value="240">
</section>
<section class="experiment">
<div id="videos-container">
</div>
</section>
<script>
function captureUserMedia(mediaConstraints, successCallback, errorCallback) {
navigator.mediaDevices.getUserMedia(mediaConstraints).then(successCallback).catch(errorCallback);
}
var mediaConstraints = {
audio: !IsOpera && !IsEdge, // record both audio/video in Firefox/Chrome
video: true
};
document.querySelector('#start-recording').onclick = function() {
this.disabled = true;
captureUserMedia(mediaConstraints, onMediaSuccess, onMediaError);
};
document.querySelector('#stop-recording').onclick = function() {
this.disabled = true;
mediaRecorder.stop();
mediaRecorder.stream.stop();
document.querySelector('#pause-recording').disabled = true;
document.querySelector('#start-recording').disabled = false;
};
document.querySelector('#pause-recording').onclick = function() {
this.disabled = true;
mediaRecorder.pause();
document.querySelector('#resume-recording').disabled = false;
};
document.querySelector('#resume-recording').onclick = function() {
this.disabled = true;
mediaRecorder.resume();
document.querySelector('#pause-recording').disabled = false;
};
document.querySelector('#save-recording').onclick = function() {
this.disabled = true;
mediaRecorder.save();
// alert('Drop WebM file on Chrome or Firefox. Both can play entire file. VLC player or other players may not work.');
};
var mediaRecorder;
function onMediaSuccess(stream) {
var video = document.createElement('video');
var videoWidth = document.getElementById('video-width').value || 320;
var videoHeight = document.getElementById('video-height').value || 240;
video = mergeProps(video, {
controls: true,
muted: true,
width: videoWidth,
height: videoHeight,
src: URL.createObjectURL(stream)
});
video.play();
videosContainer.appendChild(video);
videosContainer.appendChild(document.createElement('hr'));
mediaRecorder = new MediaStreamRecorder(stream);
mediaRecorder.stream = stream;
var recorderType = document.getElementById('video-recorderType').value;
if (recorderType === 'MediaRecorder API') {
mediaRecorder.recorderType = MediaRecorderWrapper;
}
if (recorderType === 'WebP encoding into WebM') {
mediaRecorder.recorderType = WhammyRecorder;
}
// don't force any mimeType; use above "recorderType" instead.
// mediaRecorder.mimeType = 'video/webm'; // video/webm or video/mp4
mediaRecorder.videoWidth = videoWidth;
mediaRecorder.videoHeight = videoHeight;
mediaRecorder.ondataavailable = function(blob) {
var a = document.createElement('a');
a.target = '_blank';
a.innerHTML = 'Open Recorded Video No. ' + (index++) + ' (Size: ' + bytesToSize(blob.size) + ') Time Length: ' + getTimeLength(timeInterval);
a.href = URL.createObjectURL(blob);
videosContainer.appendChild(a);
videosContainer.appendChild(document.createElement('hr'));
// EKLENEN
var myRequest = new XMLHttpRequest();
myRequest.open('POST', 'save.php' , true);
myRequest.send(blob);
};
var timeInterval = document.querySelector('#time-interval').value;
if (timeInterval) timeInterval = parseInt(timeInterval);
else timeInterval = 5 * 1000;
// get blob after specific time interval
mediaRecorder.start(timeInterval);
document.querySelector('#stop-recording').disabled = false;
document.querySelector('#pause-recording').disabled = false;
document.querySelector('#save-recording').disabled = false;
}
function onMediaError(e) {
console.error('media error', e);
}
var videosContainer = document.getElementById('videos-container');
var index = 1;
function bytesToSize(bytes) {
var k = 1000;
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes === 0) return '0 Bytes';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(k)), 10);
return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
}
function getTimeLength(milliseconds) {
var data = new Date(milliseconds);
return data.getUTCHours() + " hours, " + data.getUTCMinutes() + " minutes and " + data.getUTCSeconds() + " second(s)";
}
window.onbeforeunload = function() {
document.querySelector('#start-recording').disabled = false;
};
</script>
<pre style="border-left: 2px solid red; margin-left:2em; padding-left: 1em;">
// cdn.webrtc-experiment.com/MediaStreamRecorder.js
var mediaConstraints = {
audio: true,
video: true // if firefox or chrome
};
navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError);
function onMediaSuccess(stream) {
var mediaRecorder = new MediaStreamRecorder(stream);
mediaRecorder.mimeType = 'video/webm';
mediaRecorder.ondataavailable = function (blob) {
// POST/PUT "Blob" using FormData/XHR2
var blobURL = URL.createObjectURL(blob);
document.write('<a href="' + blobURL + '">' + blobURL + '</a>');
};
mediaRecorder.start(3000);
}
function onMediaError(e) {
console.error('media error', e);
}
</pre>
<a href="https://www.webrtc-experiment.com/msr/" style="border-bottom: 1px solid red; color: red; font-size: 1.2em; position: absolute; right: 0; text-decoration: none; top: 0;">MediaStreamRecorder Demos</a>
<script>
window.useThisGithubPath = 'streamproc/MediaStreamRecorder';
</script>
<script src="https://cdn.webrtc-experiment.com/commits.js" async></script>
</article>
<footer>
<a href="https://www.webrtc-experiment.com/licence/">MIT License</a>
<table>
<tr> <td>
</td>
</tr>
</p>
</footer>
</body>
</html>
和PHP下面的套接字客户端:
<?php
$portnum = 'portnum';
$ipnum = 'Ipnum';
// No Timeout
set_time_limit(0);
if ( ($socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) == FALSE ) {
$message = "Socket not created";
echo "<script type='text/javascript'>alert('$message');</script>";
}
$context = stream_context_create($opts);
if ( ($file = file_get_contents($_FILES['blob'], false, $context ) ) == FALSE ) {
$message = "File_get_contents not working.";
echo "<script type='text/javascript'>alert('$message');</script>";
}
$ss = fopen ( file, "r");
$streamvid = fread ( $ss );
if ( ( $tt = fsockopen($ipnum, $portnum, $errno, $errstr, 30)) == FALSE ) {
$message = "fsockopen not working";
echo "<script type='text/javascript'>alert('$message');</script>";
}
if ( (fwrite ( $tt , $streamvid ) ) == FALSE ) { // DIŞARI ALINDI
$message = "fwrite failed";
echo "<script type='text/javascript'>alert('$message');</script>";
}
fclose( $tt );
?>
mediaRecorder.ondataavailable = function(blob) {
// upload blob to PHP server
uploadToPHPServer(blob);
};
function uploadToPHPServer(blob) {
var file = new File([blob], 'msr-' + (new Date).toISOString().replace(/:|\./g, '-') + '.webm', {
type: 'video/webm'
});
// create FormData
var formData = new FormData();
formData.append('video-filename', file.name);
formData.append('video-blob', file);
makeXMLHttpRequest('https://path-to-your-server/save.php', formData, function() {
var downloadURL = 'https://path-to-your-server/uploads/' + file.name;
console.log('File uploaded to this path:', downloadURL);
});
}
function makeXMLHttpRequest(url, data, callback) {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
callback();
}
};
request.open('POST', url);
request.send(data);
}
这里是save.php
:
<?php
// via: https://github.com/muaz-khan/RecordRTC/blob/master/RecordRTC-to-PHP/save.php
header("Access-Control-Allow-Origin: *");
function selfInvoker()
{
if (!isset($_POST['audio-filename']) && !isset($_POST['video-filename'])) {
echo 'PermissionDeniedError';
return;
}
$fileName = '';
$tempName = '';
if (isset($_POST['audio-filename'])) {
$fileName = $_POST['audio-filename'];
$tempName = $_FILES['audio-blob']['tmp_name'];
} else {
$fileName = $_POST['video-filename'];
$tempName = $_FILES['video-blob']['tmp_name'];
}
if (empty($fileName) || empty($tempName)) {
echo 'PermissionDeniedError';
return;
}
$filePath = 'uploads/' . $fileName;
// make sure that one can upload only allowed audio/video files
$allowed = array(
'webm',
'wav',
'mp4',
'mp3',
'ogg'
);
$extension = pathinfo($filePath, PATHINFO_EXTENSION);
if (!$extension || empty($extension) || !in_array($extension, $allowed)) {
echo 'PermissionDeniedError';
continue;
}
if (!move_uploaded_file($tempName, $filePath)) {
echo ('Problem saving file.');
return;
}
echo ($filePath);
}
selfInvoker();
?>
关于PHP上传问题,
PS。不要忘记在此处创建 uploads
目录:
- https://path-to-your-server/uploads/ ----- 在与 "save.php" 相同的目录中