can not read property 'arrayOfDay1' of null - react-native

how to fix it?
i check array not null and go to if
but my app get error
if (this.state.arrayOfDay1.length === 0 || this.state.arrayOfDay1 === 'undefined') {
console.log(18);
var result = (this.state.arrayOfDay1).includes(i + 1);
if (result === true) {
state = 1;
// pic = require('../upload/see.png');
// this.setState({ pic: require('../upload/see.png') });
// this.setState({ key: true });
} else {
state = 0;
// pic = require('../upload/notSee.png');
// this.setState({ pic: require('../upload/notSee.png') });
}
}else {
state = 0;
console.log(1115);
}
enter image description here
enter image description here
thanks
:))))
edited
i find my problem.
i forgot to insert this before state
nicccce

Change the if condition to
if (this.state.arrayOfDay1.length != 0 && this.state.arrayOfDay1 != undefined && this.state.arrayOfDay1.length != null) {
console.log(18);
var result = (this.state.arrayOfDay1).includes(i + 1);
if (result === true) {
state = 1;
// pic = require('../upload/see.png');
// this.setState({ pic: require('../upload/see.png') });
// this.setState({ key: true });
} else {
state = 0;
// pic = require('../upload/notSee.png');
// this.setState({ pic: require('../upload/notSee.png') });
}
}else {
state = 0;
console.log(1115);
}

if(this.state.arrayOfDay1.length !== 0 && this.state.arrayOfDay1 !== undefined ) {
console.log(18);
var result = (this.state.arrayOfDay1).includes(i + 1);
if (result === true) {
state = 1;
// pic = require('../upload/see.png');
// this.setState({ pic: require('../upload/see.png') });
// this.setState({ key: true });
} else {
state = 0;
// pic = require('../upload/notSee.png');
// this.setState({ pic: require('../upload/notSee.png') });
}
}else {
state = 0;
console.log(1115);
}

Related

Vuejs-pdf print

I'm using vuejs-pdf to print some pages of my pdf and the print is not show the characters :
that's the code i'm using :
<button #click="$refs.myPdfComponent.print(100,pages)">Print </button>
<pdf v-for="i in pages" :key="i" ref="newpdf" :src="'pdf/'+src" :page="i" class="rounded border
border-info mb-4" :rotate="rotate" #progress="loadedRatio = $event" #error="error" #num-pages="numPages = $event" #link-clicked="page = $event" > </pdf>
and the pdf i'm printing is myPdfComponent the newpdf is the only the pages i need :
<pdf v-if="show" ref="myPdfComponent" class="rounded border border-info mb-4" :src="'pdf/'+src"
:page="page" :rotate="rotate" #progress="loadedRatio = $event" #error="error" #num-pages="numPages =
$event" #link-clicked="page = $event"></pdf>
Open the vue-pdf plugin directory node_modules/vue-pdf/src/pdfjsWrapper.js
and replace
import { PDFLinkService } from 'pdfjs-dist/es5/web/pdf_viewer';
var pendingOperation = Promise.resolve();
export default function(PDFJS) {
function isPDFDocumentLoadingTask(obj) {
return typeof(obj) === 'object' && obj !== null && obj.__PDFDocumentLoadingTask === true;
// or: return obj.constructor.name === 'PDFDocumentLoadingTask';
}
function createLoadingTask(src, options) {
var source;
if ( typeof(src) === 'string' )
source = { url: src };
else if ( src instanceof Uint8Array )
source = { data: src };
else if ( typeof(src) === 'object' && src !== null )
source = Object.assign({}, src);
else
throw new TypeError('invalid src type');
// source.verbosity = PDFJS.VerbosityLevel.INFOS;
// source.pdfBug = true;
// source.stopAtErrors = true;
if ( options && options.withCredentials )
source.withCredentials = options.withCredentials;
var loadingTask = PDFJS.getDocument(source);
loadingTask.__PDFDocumentLoadingTask = true; // since PDFDocumentLoadingTask is not public
if ( options && options.onPassword )
loadingTask.onPassword = options.onPassword;
if ( options && options.onProgress )
loadingTask.onProgress = options.onProgress;
return loadingTask;
}
function PDFJSWrapper(canvasElt, annotationLayerElt, emitEvent) {
var pdfDoc = null;
var pdfPage = null;
var pdfRender = null;
var canceling = false;
canvasElt.getContext('2d').save();
function clearCanvas() {
canvasElt.getContext('2d').clearRect(0, 0, canvasElt.width, canvasElt.height);
}
function clearAnnotations() {
while ( annotationLayerElt.firstChild )
annotationLayerElt.removeChild(annotationLayerElt.firstChild);
}
this.destroy = function() {
if ( pdfDoc === null )
return;
// Aborts all network requests and destroys worker.
pendingOperation = pdfDoc.destroy();
pdfDoc = null;
}
this.getResolutionScale = function() {
return canvasElt.offsetWidth / canvasElt.width;
}
this.printPage = function(dpi, pageNumberOnly) {
if ( pdfPage === null )
return;
// 1in == 72pt
// 1in == 96px
var PRINT_RESOLUTION = dpi === undefined ? 150 : dpi;
var PRINT_UNITS = PRINT_RESOLUTION / 72.0;
var CSS_UNITS = 96.0 / 72.0;
/*var iframeElt = document.createElement('iframe');
function removeIframe() {
iframeElt.parentNode.removeChild(iframeElt);
}*/
var printContainerElement = document.createElement('div');
printContainerElement.setAttribute('id', 'print-container')
function removePrintContainer() {
printContainerElement.parentNode.removeChild(printContainerElement);
}
new Promise(function(resolve, reject) {
/*
iframeElt.frameBorder = '0';
iframeElt.scrolling = 'no';
iframeElt.width = '0px;'
iframeElt.height = '0px;'
iframeElt.style.cssText = 'position: absolute; top: 0; left: 0';
iframeElt.onload = function() {
resolve(this.contentWindow);
}
window.document.body.appendChild(iframeElt);*/
printContainerElement.frameBorder = '0';
printContainerElement.scrolling = 'no';
printContainerElement.width = '0px;'
printContainerElement.height = '0px;'
printContainerElement.style.cssText = 'position: absolute; top: 0; left: 0';
window.document.body.appendChild(printContainerElement);
resolve(window)
})
.then(function(win) {
win.document.title = '';
return pdfDoc.getPage(1)
.then(function(page) {
var viewport = page.getViewport({ scale: 1 });
//win.document.head.appendChild(win.document.createElement('style')).textContent =
printContainerElement.appendChild(win.document.createElement('style')).textContent =
'#supports ((size:A4) and (size:1pt 1pt)) {' +
'#page { margin: 1pt; size: ' + ((viewport.width * PRINT_UNITS) / CSS_UNITS) + 'pt ' + ((viewport.height * PRINT_UNITS) / CSS_UNITS) + 'pt; }' +
'}' +
'#print-canvas { display: none }' +
'#media print {' +
'body { margin: 0 }' +
'canvas { page-break-before: avoid; page-break-after: always; page-break-inside: avoid }' +
'#print-canvas { page-break-before: avoid; page-break-after: always; page-break-inside: avoid; display: block }' +
'body > *:not(#print-container) { display: none; }' +
'}'+
'#media screen {' +
'body { margin: 0 }' +
'}'+
''
return win;
})
})
.then(function(win) {
var allPages = [];
for ( var pageNumber = 1; pageNumber <= pdfDoc.numPages; ++pageNumber ) {
if ( pageNumberOnly !== undefined && pageNumberOnly.indexOf(pageNumber) === -1 )
continue;
allPages.push(
pdfDoc.getPage(pageNumber)
.then(function(page) {
var viewport = page.getViewport({ scale: 1 });
//var printCanvasElt = win.document.body.appendChild(win.document.createElement('canvas'));
var printCanvasElt = printContainerElement.appendChild(win.document.createElement('canvas'));
printCanvasElt.setAttribute('id', 'print-canvas')
printCanvasElt.width = (viewport.width * PRINT_UNITS);
printCanvasElt.height = (viewport.height * PRINT_UNITS);
return page.render({
canvasContext: printCanvasElt.getContext('2d'),
transform: [ // Additional transform, applied just before viewport transform.
PRINT_UNITS, 0, 0,
PRINT_UNITS, 0, 0
],
viewport: viewport,
intent: 'print'
}).promise;
})
);
}
Promise.all(allPages)
.then(function() {
win.focus(); // Required for IE
if (win.document.queryCommandSupported('print')) {
win.document.execCommand('print', false, null);
} else {
win.print();
}
removePrintContainer();
})
.catch(function(err) {
removePrintContainer();
emitEvent('error', err);
})
})
}
this.renderPage = function(rotate) {
if ( pdfRender !== null ) {
if ( canceling )
return;
canceling = true;
pdfRender.cancel();
return;
}
if ( pdfPage === null )
return;
var pageRotate = (pdfPage.rotate === undefined ? 0 : pdfPage.rotate) + (rotate === undefined ? 0 : rotate);
var scale = canvasElt.offsetWidth / pdfPage.getViewport({ scale: 1 }).width * (window.devicePixelRatio || 1);
var viewport = pdfPage.getViewport({ scale: scale, rotation:pageRotate });
emitEvent('page-size', viewport.width, viewport.height, scale);
canvasElt.width = viewport.width;
canvasElt.height = viewport.height;
pdfRender = pdfPage.render({
canvasContext: canvasElt.getContext('2d'),
viewport: viewport
});
annotationLayerElt.style.visibility = 'hidden';
clearAnnotations();
var viewer = {
scrollPageIntoView: function(params) {
emitEvent('link-clicked', params.pageNumber)
},
};
var linkService = new PDFLinkService();
linkService.setDocument(pdfDoc);
linkService.setViewer(viewer);
pendingOperation = pendingOperation.then(function() {
var getAnnotationsOperation =
pdfPage.getAnnotations({ intent: 'display' })
.then(function(annotations) {
PDFJS.AnnotationLayer.render({
viewport: viewport.clone({ dontFlip: true }),
div: annotationLayerElt,
annotations: annotations,
page: pdfPage,
linkService: linkService,
renderInteractiveForms: false
});
});
var pdfRenderOperation =
pdfRender.promise
.then(function() {
annotationLayerElt.style.visibility = '';
canceling = false;
pdfRender = null;
})
.catch(function(err) {
pdfRender = null;
if ( err instanceof PDFJS.RenderingCancelledException ) {
canceling = false;
this.renderPage(rotate);
return;
}
emitEvent('error', err);
}.bind(this))
return Promise.all([getAnnotationsOperation, pdfRenderOperation]);
}.bind(this));
}
this.forEachPage = function(pageCallback) {
var numPages = pdfDoc.numPages;
(function next(pageNum) {
pdfDoc.getPage(pageNum)
.then(pageCallback)
.then(function() {
if ( ++pageNum <= numPages )
next(pageNum);
})
})(1);
}
this.loadPage = function(pageNumber, rotate) {
pdfPage = null;
if ( pdfDoc === null )
return;
pendingOperation = pendingOperation.then(function() {
return pdfDoc.getPage(pageNumber);
})
.then(function(page) {
pdfPage = page;
this.renderPage(rotate);
emitEvent('page-loaded', page.pageNumber);
}.bind(this))
.catch(function(err) {
clearCanvas();
clearAnnotations();
emitEvent('error', err);
});
}
this.loadDocument = function(src) {
pdfDoc = null;
pdfPage = null;
emitEvent('num-pages', undefined);
if ( !src ) {
canvasElt.removeAttribute('width');
canvasElt.removeAttribute('height');
clearAnnotations();
return;
}
// wait for pending operation ends
pendingOperation = pendingOperation.then(function() {
var loadingTask;
if ( isPDFDocumentLoadingTask(src) ) {
if ( src.destroyed ) {
emitEvent('error', new Error('loadingTask has been destroyed'));
return
}
loadingTask = src;
} else {
loadingTask = createLoadingTask(src, {
onPassword: function(updatePassword, reason) {
var reasonStr;
switch (reason) {
case PDFJS.PasswordResponses.NEED_PASSWORD:
reasonStr = 'NEED_PASSWORD';
break;
case PDFJS.PasswordResponses.INCORRECT_PASSWORD:
reasonStr = 'INCORRECT_PASSWORD';
break;
}
emitEvent('password', updatePassword, reasonStr);
},
onProgress: function(status) {
var ratio = status.loaded / status.total;
emitEvent('progress', Math.min(ratio, 1));
}
});
}
return loadingTask.promise;
})
.then(function(pdf) {
pdfDoc = pdf;
emitEvent('num-pages', pdf.numPages);
emitEvent('loaded');
})
.catch(function(err) {
clearCanvas();
clearAnnotations();
emitEvent('error', err);
})
}
annotationLayerElt.style.transformOrigin = '0 0';
}
return {
createLoadingTask: createLoadingTask,
PDFJSWrapper: PDFJSWrapper,
}
}

hide index.php from ajax load search in osclass

link look like http://localhost/index.php?page=search&sOrder=dt_pub_date&iOrderType=desc&sPattern=car
// AJAX SEARCH
$('body#body-search').on('change click', '.link-check-box a, .filter-remove a, form.search-side-form input:not(.term), body#body-search #sub-nav a, #home-cat a, #sub-cat a, form.search-side-form select, .sort-it a, .user-type a,.list-grid a, .paginate a', function(event) {
var ajaxStop = false;
if(ajaxSearch == 1 && event.type != 'change') {
event.preventDefault();
}
// Disable on mobile devices when input selected from fancybox
if($(event.target).closest('.search-mobile-filter-box').length) {
if(!$(event.target).closest('#search-sort').length && !$(event.target).closest('.sub-line').length) { // it may not be required
var ajaxStop = true;
//return false;
}
}
var sidebarReload = true;
if($(this).closest('.sidebar-hooks').length || $(event.target).attr('name') == 'locUpdate') {
sidebarReload = false;
}
var sidebar = $('.filter form.search-side-form');
var ajaxSearchUrl = '';
if (event.type == 'click') {
if(typeof $(this).attr('href') !== typeof undefined && $(this).attr('href') !== false) {
ajaxSearchUrl = $(this).attr('href');
}
} else if (event.type == 'change') {
ajaxSearchUrl = baseDir + "index.php?" + sidebar.find(':input[value!=""]').serialize();
}
if(ajaxSearch == 1 && $('input[name="ajaxRun"]').val() != "1" && (ajaxSearchUrl != '#' && ajaxSearchUrl != '') && !ajaxStop) {
if(ajaxSearchUrl == $(location).attr('href')) {
return false;
}
sidebar.find('.init-search').addClass('btn-loading').addClass('disabled').attr('disabled', true);
sidebar.find('input[name="ajaxRun"]').val("1");
$('#search-items').addClass('loading');
$.ajax({
url: ajaxSearchUrl,
type: "GET",
success: function(response){
var length = response.length;
var data = $(response).contents().find('#main').html();
var bread = $(response).contents().find('ul.breadcrumb');
var filter = $(response).contents().find('.filter').html();
sidebar.find('.init-search').removeClass('btn-loading').removeClass('disabled').attr('disabled', false);
sidebar.find('input[name="ajaxRun"]').val("");
$('#main').fadeOut(0, function(){
$('#main').html(data).show(0);
$('#search-items').hide(0);
$('#search-items').removeClass('loading');
$('#search-items').show(0).css('opacity', 0).css('margin-top', '50px').css('margin-bottom', '-50px').animate( { opacity: 1, marginTop:'0', marginBottom:'0'} , 300);
});
if(sidebarReload) {
$('.filter').html(filter);
}
$('ul.breadcrumb').html(bread);

React Native SectionList (title, data) - Search in the data field

I am trying to build Search function in SectionList. I have search inside the 'data' (second field) and not inside 'title' but I am not able to make it work.
My Data is about the Flat / resident details of an Apartment -
sectiondata =
[{"title":"GROUND FLOOR",
"data":[
{"id":"48","res_type":"owner","user_name":"Ashwani","flat_id":"1","flat_name":"001","floor_no":"GROUND FLOOR","floor_int":"0","signal_player_id":"aa","user_phone":"98855550"},
{"id":"49","res_type":"owner","user_name":"Rahul","flat_id":"2","flat_name":"002","floor_no":"GROUND FLOOR","floor_int":"0","signal_player_id":"aa","user_phone":"999999"}
]
}]
I am trying something like this but it is not working.
searchFilterFunction = (text) => {
let search = text.toLowerCase();
this.setState({
check: this.state.sectiondata.filter(
obj => obj.data['flat_name'].toLowerCase().includes(search))
});
}
How to filter data base on name? Please assist here.
Thanks.
You can try to search like this:
onChangeText(text) {
if (text.trim().length > 0) {
var temp = []
sectiondata.map((item) => {
var dataItem = {};
var brandData = [];
item.data.map((searchItem) => {
let flatName = searchItem.flat_name
if (flatName.match(text)) {
brandData.push(searchItem);
}
})
if (brandData.length > 0) {
} else {
return null;
}
dataItem.brandData = brandData;
temp.push(dataItem);
this.setState({
sectiondata: temp
})
})
} else {
this.setState({
sectiondata: this.state.tempData
})
}
}
searchFilterFunction(text) {
if( text == undefined || text == '') {
this.setState({
sectiondata: this.arrayholder
})
return;
}
if (text.trim().length > 0) {
var temp = []
this.state.sectiondata.map((item) => {
var dataItem = {};
var title = item.title;
var brandData = [];
item.data.map((searchItem) => {
let flatName = searchItem.flat_name
if (flatName.match(text)) {
brandData.push(searchItem);
}
})
if (brandData.length > 0) {
} else {
return null;
}
dataItem.title = title;
dataItem.data = brandData;
temp.push(dataItem);
this.setState({
sectiondata: temp
})
})

Webrtc video chat not working in different networks

I am trying to implement video chat with webrtc using code from google code labs . It works fine on same network but does not work on different network. i have installed coturn on my server. I am not sure if it is working correctly.
Any one used google codelabs code and made it working?
This is the modified main.js file
'use strict';
var isChannelReady = false;
var isInitiator = false;
var isStarted = false;
var localStream;
var pc;
var remoteStream;
var turnReady;
var pcConfig = {
"iceServers":[
{'urls': 'stun:stun.l.google.com:19302'},
{"urls":["turn:78.129.167.90"],"username":"wyzturner1","credential":"wyzturnp2ss"}]
};
// Set up audio and video regardless of what devices are present.
var sdpConstraints = {
offerToReceiveAudio: true,
offerToReceiveVideo: true
};
/////////////////////////////////////////////
var room = 'foo';
// Could prompt for room name:
// room = prompt('Enter room name:');
var socket = io.connect('https://www.samplesite.com:8080');
if (room !== '') {
socket.emit('create or join', room);
console.log('Attempted to create or join room', room);
}
socket.on('created', function(room) {
console.log('Created room ' + room);
isInitiator = true;
});
socket.on('full', function(room) {
console.log('Room ' + room + ' is full');
});
socket.on('join', function (room){
console.log('Another peer made a request to join room ' + room);
console.log('This peer is the initiator of room ' + room + '!');
isChannelReady = true;
});
socket.on('joined', function(room) {
console.log('joined: ' + room);
isChannelReady = true;
});
socket.on('log', function(array) {
console.log.apply(console, array);
});
////////////////////////////////////////////////
function sendMessage(message) {
console.log('Client sending message: ', message);
socket.emit('message', message);
}
// This client receives a message
socket.on('message', function(message) {
console.log('Client received message:', message);
if (message === 'got user media') {
maybeStart();
} else if (message.type === 'offer') {
if (!isInitiator && !isStarted) {
maybeStart();
}
pc.setRemoteDescription(new RTCSessionDescription(message));
doAnswer();
} else if (message.type === 'answer' && isStarted) {
pc.setRemoteDescription(new RTCSessionDescription(message));
} else if (message.type === 'candidate' && isStarted) {
var candidate = new RTCIceCandidate({
sdpMLineIndex: message.label,
candidate: message.candidate
});
pc.addIceCandidate(candidate);
} else if (message === 'bye' && isStarted) {
handleRemoteHangup();
}
});
////////////////////////////////////////////////////
var localVideo = document.querySelector('#localVideo');
var remoteVideo = document.querySelector('#remoteVideo');
navigator.mediaDevices.getUserMedia({
audio: false,
video: true
})
.then(gotStream)
.catch(function(e) {
alert('getUserMedia() error: ' + e.name);
});
function gotStream(stream) {
console.log('Adding local stream.');
localVideo.src = window.URL.createObjectURL(stream);
localStream = stream;
sendMessage('got user media');
if (isInitiator) {
maybeStart();
}
}
var constraints = {
video: true
};
console.log('Getting user media with constraints', constraints);
//if (location.hostname !== 'localhost') {
// requestTurn(
// 'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913'
// );
//}
function maybeStart() {
console.log('>>>>>>> maybeStart() ', isStarted, localStream, isChannelReady);
if (!isStarted && typeof localStream !== 'undefined' && isChannelReady) {
console.log('>>>>>> creating peer connection');
createPeerConnection();
isStarted = true;
console.log('isInitiator', isInitiator);
if (isInitiator) {
doCall();
}
}
}
window.onbeforeunload = function() {
sendMessage('bye');
};
/////////////////////////////////////////////////////////
function createPeerConnection() {
try {
pc = new RTCPeerConnection(pcConfig);
pc.addStream(localStream);
pc.onicecandidate = handleIceCandidate;
pc.onaddstream = handleRemoteStreamAdded;
pc.oniceconnectionstatechange = function(){
console.log('ICE state: ',pc.iceConnectionState);
}
pc.onremovestream = handleRemoteStreamRemoved;
console.log('Created RTCPeerConnnection');
} catch (e) {
console.log('Failed to create PeerConnection, exception: ' + e.message);
alert('Cannot create RTCPeerConnection object.');
return;
}
}
function handleIceCandidate(event) {
console.log('icecandidate event: ', event);
if (event.candidate) {
sendMessage({
type: 'candidate',
label: event.candidate.sdpMLineIndex,
id: event.candidate.sdpMid,
candidate: event.candidate.candidate
});
} else {
console.log('End of candidates.');
}
}
function handleRemoteStreamAdded(event) {
console.log('Remote stream added.');
remoteVideo.src = window.URL.createObjectURL(event.stream);
remoteStream = event.stream;
}
function handleCreateOfferError(event) {
console.log('createOffer() error: ', event);
}
function doCall() {
console.log('Sending offer to peer');
pc.createOffer(setLocalAndSendMessage, handleCreateOfferError);
}
function doAnswer() {
console.log('Sending answer to peer.');
pc.createAnswer().then(
setLocalAndSendMessage,
onCreateSessionDescriptionError
);
}
function setLocalAndSendMessage(sessionDescription) {
// Set Opus as the preferred codec in SDP if Opus is present.
// sessionDescription.sdp = preferOpus(sessionDescription.sdp);
pc.setLocalDescription(sessionDescription);
console.log('setLocalAndSendMessage sending message', sessionDescription);
sendMessage(sessionDescription);
}
function onCreateSessionDescriptionError(error) {
trace('Failed to create session description: ' + error.toString());
}
function requestTurn(turnURL) {
var turnExists = false;
for (var i in pcConfig.iceServers) {
if (pcConfig.iceServers[i].urls.substr(0, 5) === 'turn:') {
turnExists = true;
turnReady = true;
break;
}
}
// if (!turnExists) {
// console.log('Getting TURN server from ', turnURL);
// // No TURN server. Get one from computeengineondemand.appspot.com:
// var xhr = new XMLHttpRequest();
// xhr.onreadystatechange = function() {
// if (xhr.readyState === 4 && xhr.status === 200) {
// var turnServer = JSON.parse(xhr.responseText);
// console.log('Got TURN server: ', turnServer);
// pcConfig.iceServers.push({
// 'url': 'turn:' + turnServer.username + '#' + turnServer.turn,
// 'credential': turnServer.password
// });
// turnReady = true;
// }
// };
// xhr.open('GET', turnURL, true);
// xhr.send();
// }
}
function handleRemoteStreamAdded(event) {
console.log('Remote stream added.');
remoteVideo.src = window.URL.createObjectURL(event.stream);
remoteStream = event.stream;
}
function handleRemoteStreamRemoved(event) {
console.log('Remote stream removed. Event: ', event);
}
function hangup() {
console.log('Hanging up.');
stop();
sendMessage('bye');
}
function handleRemoteHangup() {
console.log('Session terminated.');
stop();
isInitiator = false;
}
function stop() {
isStarted = false;
// isAudioMuted = false;
// isVideoMuted = false;
pc.close();
pc = null;
}
///////////////////////////////////////////
// Set Opus as the default audio codec if it's present.
function preferOpus(sdp) {
var sdpLines = sdp.split('\r\n');
var mLineIndex;
// Search for m line.
for (var i = 0; i < sdpLines.length; i++) {
if (sdpLines[i].search('m=audio') !== -1) {
mLineIndex = i;
break;
}
}
if (mLineIndex === null) {
return sdp;
}
// If Opus is available, set it as the default in m line.
for (i = 0; i < sdpLines.length; i++) {
if (sdpLines[i].search('opus/48000') !== -1) {
var opusPayload = extractSdp(sdpLines[i], /:(\d+) opus\/48000/i);
if (opusPayload) {
sdpLines[mLineIndex] = setDefaultCodec(sdpLines[mLineIndex],
opusPayload);
}
break;
}
}
// Remove CN in m line and sdp.
sdpLines = removeCN(sdpLines, mLineIndex);
sdp = sdpLines.join('\r\n');
return sdp;
}
function extractSdp(sdpLine, pattern) {
var result = sdpLine.match(pattern);
return result && result.length === 2 ? result[1] : null;
}
// Set the selected codec to the first in m line.
function setDefaultCodec(mLine, payload) {
var elements = mLine.split(' ');
var newLine = [];
var index = 0;
for (var i = 0; i < elements.length; i++) {
if (index === 3) { // Format of media starts from the fourth.
newLine[index++] = payload; // Put target payload to the first.
}
if (elements[i] !== payload) {
newLine[index++] = elements[i];
}
}
return newLine.join(' ');
}
// Strip CN from sdp before CN constraints is ready.
function removeCN(sdpLines, mLineIndex) {
var mLineElements = sdpLines[mLineIndex].split(' ');
// Scan from end for the convenience of removing an item.
for (var i = sdpLines.length - 1; i >= 0; i--) {
var payload = extractSdp(sdpLines[i], /a=rtpmap:(\d+) CN\/\d+/i);
if (payload) {
var cnPos = mLineElements.indexOf(payload);
if (cnPos !== -1) {
// Remove CN payload from m line.
mLineElements.splice(cnPos, 1);
}
// Remove CN line in sdp
sdpLines.splice(i, 1);
}
}
sdpLines[mLineIndex] = mLineElements.join(' ');
return sdpLines;
}

WebRTC + JSEP + Google Channel API - cannot receive remoteStream

I've been trying to get this works, but I don't know what's wrong, can you guys help me? I tried WebRTC code with modification like this.
Both caller and callee enter the web
Web will create channel based on their username
Caller clicks the call button and sends message to spesific channel to some user's username. When caller clicks the call button, he then creates peerConnection and adds localStream
Callee will receive message, and the process goes on like WebRTC sample code. When callee receives an offer, he then creates peerConnection and adds localStream, then creates and sends answer
My code goes like this
var my_username = '{{ current_username }}';
var friend;
var localVideo;
var remoteVideo;
var localStream;
var remoteStream;
var channel;
var channelReady = false;
var pc;
var socket;
var started = false;
// Set up audio and video regardless of what devices are present.
var mediaConstraints = {'mandatory': {
'OfferToReceiveAudio':true,
'OfferToReceiveVideo':true }};
var isVideoMuted = false;
var isAudioMuted = false;
function choiceFriendInitialize() {
var choice_visible = false;
$('ul#friendlist > li').click(function(e) {
$(this).css('background-color', '#808080');
friend = $(this).text();
var choice = $('ul#choice');
choice_visible = true;
choice.css('display', 'inline-block');
choice.css('top', e.pageY);
choice.css('left', e.pageX);
});
// trigger call from here
$('li#call').click(function() {
$('ul#friendlist > li').css('background-color', 'transparent');
$('ul#choice').css('display', 'none');
choice_visible = false;
// call
maybeStart();
doCall();
});
$('li#unfriend').click(function() {
$('ul#friendlist > li').css('background-color', 'transparent');
$('ul#choice').css('display', 'none');
choice_visible = false;
});
$("body").mouseup(function(){
if (choice_visible) {
$('ul#friendlist > li').css('background-color', 'transparent');
$('ul#choice').css('display', 'none');
choice_visible = false;
}
});
}
function initialize() {
console.log("Initializing..");
choiceFriendInitialize();
localVideo = document.getElementById("localVideo");
remoteVideo = document.getElementById("remoteVideo");
openChannel();
doGetUserMedia();
}
function openChannel() {
console.log("Opening channel.");
var channel = new goog.appengine.Channel('{{ token }}');
var handler = {
'onopen': onChannelOpened,
'onmessage': onChannelMessage,
'onerror': onChannelError,
'onclose': onChannelClosed
};
socket = channel.open(handler);
}
function doGetUserMedia() {
// Call into getUserMedia via the polyfill (adapter.js).
var constraints = {"mandatory": {}, "optional": []};
try {
getUserMedia({'audio':true, 'video':constraints}, onUserMediaSuccess, onUserMediaError);
console.log("Requested access to local media with mediaConstraints:\n" + " \"" + JSON.stringify(constraints) + "\"");
} catch (e) {
alert("getUserMedia() failed. Is this a WebRTC capable browser?");
console.log("getUserMedia failed with exception: " + e.message);
}
}
function createPeerConnection() {
var pc_config = {"iceServers": [{"url": "stun:stun.l.google.com:19302"}]};
try {
// Create an RTCPeerConnection via the polyfill (adapter.js).
pc = new RTCPeerConnection(pc_config);
pc.onicecandidate = onIceCandidate;
console.log("Created RTCPeerConnnection with config:\n" + " \"" + JSON.stringify(pc_config) + "\".");
} catch (e) {
console.log("Failed to create PeerConnection, exception: " + e.message);
alert("Cannot create RTCPeerConnection object; WebRTC is not supported by this browser.");
return;
}
pc.onconnecting = onSessionConnecting;
pc.onopen = onSessionOpened;
pc.onaddstream = onRemoteStreamAdded;
pc.onremovestream = onRemoteStreamRemoved;
}
function maybeStart() {
if (!started && localStream && channelReady) {
console.log("Creating PeerConnection.");
createPeerConnection();
console.log("Adding local stream.");
pc.addStream(localStream);
started = true;
// Caller initiates offer to peer.
//if (initiator)
//doCall();
}
}
function doCall() {
console.log("Sending offer to peer.");
pc.createOffer(setLocalAndSendMessage, null, mediaConstraints);
}
function doAnswer() {
console.log("Sending answer to peer.");
pc.createAnswer(setLocalAndSendMessage, null, mediaConstraints);
}
function setLocalAndSendMessage(sessionDescription) {
// Set Opus as the preferred codec in SDP if Opus is present.
sessionDescription.sdp = preferOpus(sessionDescription.sdp);
pc.setLocalDescription(sessionDescription);
sendMessage({from: my_username, to: friend}, sessionDescription);
}
function sendMessage(client, message) {
console.log('C->S: ' + JSON.stringify(message));
var xhr = new XMLHttpRequest();
xhr.open('POST', '/send', true);
xhr.setRequestHeader("Content-type","application/json");
var msgString = {send_info: client, data_message: message};
xhr.send(JSON.stringify(msgString));
}
function processSignalingMessage(message) {
var msg = JSON.parse(message);
var data_message = msg.data_message;
var send_info = msg.send_info;
if (data_message.type === 'offer') {
// Callee creates PeerConnection
if (!started)
maybeStart();
pc.setRemoteDescription(new RTCSessionDescription(data_message));
friend = send_info.from;
doAnswer();
} else if (data_message.type === 'answer' && started) {
pc.setRemoteDescription(new RTCSessionDescription(data_message));
} else if (data_message.type === 'candidate' && started) {
var candidate = new RTCIceCandidate({sdpMLineIndex:data_message.label, candidate:data_message.candidate});
pc.addIceCandidate(candidate);
} else if (data_message.type === 'bye' && started) {
onRemoteHangup();
}
}
function onChannelOpened() {
console.log('Channel opened.');
channelReady = true;
}
function onChannelMessage(message) {
console.log('S->C: ' + message.data);
processSignalingMessage(message.data);
}
function onChannelError() {
console.log('Channel error.');
}
function onChannelClosed() {
console.log('Channel closed.');
}
function onUserMediaSuccess(stream) {
console.log("User has granted access to local media.");
// Call the polyfill wrapper to attach the media stream to this element.
attachMediaStream(localVideo, stream);
localVideo.style.opacity = 1;
localStream = stream;
// Caller creates PeerConnection.
//if (initiator) maybeStart();
}
function onUserMediaError(error) {
console.log("Failed to get access to local media. Error code was " + error.code);
alert("Failed to get access to local media. Error code was " + error.code + ".");
}
function onIceCandidate(event) {
if (event.candidate) {
sendMessage({from: my_username, to: friend}, {type: 'candidate',
label: event.candidate.sdpMLineIndex,
id: event.candidate.sdpMid,
candidate: event.candidate.candidate});
} else {
console.log("End of candidates.");
}
}
function onSessionConnecting(message) {
console.log("Session connecting.");
}
function onSessionOpened(message) {
console.log("Session opened.");
}
function onRemoteStreamAdded(event) {
console.log("Remote stream added.");
attachMediaStream(remoteVideo, event.stream);
remoteStream = event.stream;
waitForRemoteVideo();
}
function onRemoteStreamRemoved(event) {
console.log("Remote stream removed.");
}
function onHangup() {
console.log("Hanging up.");
transitionToDone();
stop();
// will trigger BYE from server
socket.close();
}
function onRemoteHangup() {
console.log('Session terminated.');
transitionToWaiting();
stop();
}
function stop() {
started = false;
isAudioMuted = false;
isVideoMuted = false;
pc.close();
pc = null;
}
function waitForRemoteVideo() {
if (remoteStream.videoTracks.length === 0 || remoteVideo.currentTime > 0) {
console.log('ada remote stream');
transitionToActive();
} else {
console.log('ga ada remote stream');
setTimeout(waitForRemoteVideo, 100);
}
}
function transitionToActive() {
remoteVideo.style.opacity = 1;
}
function transitionToWaiting() {
remoteVideo.style.opacity = 0;
}
function transitionToDone() {
localVideo.style.opacity = 0;
remoteVideo.style.opacity = 0;
}
function toggleVideoMute() {
if (localStream.videoTracks.length === 0) {
console.log("No local video available.");
return;
}
if (isVideoMuted) {
for (i = 0; i < localStream.videoTracks.length; i++) {
localStream.videoTracks[i].enabled = true;
}
console.log("Video unmuted.");
} else {
for (i = 0; i < localStream.videoTracks.length; i++) {
localStream.videoTracks[i].enabled = false;
}
console.log("Video muted.");
}
isVideoMuted = !isVideoMuted;
}
function toggleAudioMute() {
if (localStream.audioTracks.length === 0) {
console.log("No local audio available.");
return;
}
if (isAudioMuted) {
for (i = 0; i < localStream.audioTracks.length; i++) {
localStream.audioTracks[i].enabled = true;
}
console.log("Audio unmuted.");
} else {
for (i = 0; i < localStream.audioTracks.length; i++){
localStream.audioTracks[i].enabled = false;
}
console.log("Audio muted.");
}
isAudioMuted = !isAudioMuted;
}
setTimeout(initialize, 1);
// Send BYE on refreshing(or leaving) a demo page
// to ensure the room is cleaned for next session.
window.onbeforeunload = function() {
sendMessage({from: my_username, to: friend}, {type: 'bye'});
//Delay 100ms to ensure 'bye' arrives first.
setTimeout(function(){}, 100);
}
// Ctrl-D: toggle audio mute; Ctrl-E: toggle video mute.
// On Mac, Command key is instead of Ctrl.
// Return false to screen out original Chrome shortcuts.
document.onkeydown = function() {
if (navigator.appVersion.indexOf("Mac") != -1) {
if (event.metaKey && event.keyCode === 68) {
toggleAudioMute();
return false;
}
if (event.metaKey && event.keyCode === 69) {
toggleVideoMute();
return false;
}
} else {
if (event.ctrlKey && event.keyCode === 68) {
toggleAudioMute();
return false;
}
if (event.ctrlKey && event.keyCode === 69) {
toggleVideoMute();
return false;
}
}
}
// Set Opus as the default audio codec if it's present.
function preferOpus(sdp) {
var sdpLines = sdp.split('\r\n');
// Search for m line.
for (var i = 0; i < sdpLines.length; i++) {
if (sdpLines[i].search('m=audio') !== -1) {
var mLineIndex = i;
break;
}
}
if (mLineIndex === null)
return sdp;
// If Opus is available, set it as the default in m line.
for (var i = 0; i < sdpLines.length; i++) {
if (sdpLines[i].search('opus/48000') !== -1) {
var opusPayload = extractSdp(sdpLines[i], /:(\d+) opus\/48000/i);
if (opusPayload)
sdpLines[mLineIndex] = setDefaultCodec(sdpLines[mLineIndex], opusPayload);
break;
}
}
// Remove CN in m line and sdp.
sdpLines = removeCN(sdpLines, mLineIndex);
sdp = sdpLines.join('\r\n');
return sdp;
}
function extractSdp(sdpLine, pattern) {
var result = sdpLine.match(pattern);
return (result && result.length == 2)? result[1]: null;
}
// Set the selected codec to the first in m line.
function setDefaultCodec(mLine, payload) {
var elements = mLine.split(' ');
var newLine = new Array();
var index = 0;
for (var i = 0; i < elements.length; i++) {
if (index === 3) // Format of media starts from the fourth.
newLine[index++] = payload; // Put target payload to the first.
if (elements[i] !== payload)
newLine[index++] = elements[i];
}
return newLine.join(' ');
}
// Strip CN from sdp before CN constraints is ready.
function removeCN(sdpLines, mLineIndex) {
var mLineElements = sdpLines[mLineIndex].split(' ');
// Scan from end for the convenience of removing an item.
for (var i = sdpLines.length-1; i >= 0; i--) {
var payload = extractSdp(sdpLines[i], /a=rtpmap:(\d+) CN\/\d+/i);
if (payload) {
var cnPos = mLineElements.indexOf(payload);
if (cnPos !== -1) {
// Remove CN payload from m line.
mLineElements.splice(cnPos, 1);
}
// Remove CN line in sdp
sdpLines.splice(i, 1);
}
}
sdpLines[mLineIndex] = mLineElements.join(' ');
return sdpLines;
}
When it comes to waitForRemoteVideo, the function calls the else condition. But the blob url for remoteVideo exists.
It's funny that I've been searching for the error and re-writing the code for like three times, and suddenly after posted my question here, I realized my mistake.
Here in the function processSignallingMessage..
if (data_message.type === 'offer') {
// Callee creates PeerConnection
if (!started)
maybeStart();
pc.setRemoteDescription(new RTCSessionDescription(data_message));
friend = send_info.from;
doAnswer();
} else ....
Should be like this:
if (data_message.type === 'offer') {
friend = send_info.from;
// Callee creates PeerConnection
if (!started)
maybeStart();
pc.setRemoteDescription(new RTCSessionDescription(data_message));
doAnswer();
} else ....
because callee need variable friend to be filled before sending candidate message.