react native ble plx - Bluetooth is not supported in ios - react-native

When I start device scan by calling the method startDevcieScan(), most of the time "bluetooth is not supported" alert comes. This happens only in ios. I am unable to figure out why its happening.I tested the code on actual devices - iphone 5s, 6s and ipad.
Below is the code snippet:
let that = this;
let deviceList = [];
let count = 0;
that.manager.startDeviceScan(["1802"], null, (error, device) => {
if (error) {
try {
alert(`${error.message}`);
Log.info(`BLE scan error: ${error.message}`);
} catch (e) {
Log.info(`BLE scan error: ${error}`);
}
return;
}
let localDeviceList = deviceList;
let exists = false;
localDeviceList.map((d) => {
if (d.id == device.id) {
exists = true;
}
});
if (!exists) {
deviceList.push(device);
this.homeScreen.setState({listBLEDevices: deviceList});
let arr = this.homeScreen.state.availableDevices;
arr.push({id: device.id, name: device.name, connected: false});
this.homeScreen.setState({availableDevices: arr});
}
});
};

Related

How can i access to USB Camera with Device ID on Electron

I have two camera on my laptop. (Integrated and Usb) I didn't get capture from my usb camera when i listed and choose device as USB camera.
I am sending the device id parameter for getUserMedia like;
Camera.js (This is different )
const { ipcRenderer } = require('electron');
var video = document.querySelector('#videoElement');
let deviceId;
function stop(e) {
var stream = video.srcObject;
var tracks = stream.getTracks();
for (var i = 0; i < tracks.length; i++) {
var track = tracks[i];
track.stop();
}
video.srcObject = null;
}
ipcRenderer.on('camera-id', (event, arg) => {
//alert(arg);
if (navigator.mediaDevices.getUserMedia) {
const constraints = {
video: {
deviceId: {
exact: arg,
},
},
};
navigator.mediaDevices
.getUserMedia(constraints)
.then(function (stream) {
alert(stream);
video.srcObject = stream;
})
.catch(function (err0r) {
alert(err0r);
});
}
});
I am getting "overconstrainederror" if i use exact parameter. If i give device id parameter directly its working fine but capture always coming from integrated camera. Never switch to USB camera.
const constraints = {
video: {
deviceId: arg,
},
};
Update:
DeviceId parameter is not functional. If i choose width and heigth in constrains camera is automatically opened whic is available for resolution.

Expo AV playback callback strange behaviour with state properties

I am starting to go nuts with this one. I am recording an audio, once I stop the recording as part of the this process I also load the audio so that it is ready to be played back when necessary and here I do setOnPlaybackStatusUpdate. I use the playback callback so that I can update a my currentSeconds state based on positionMillis.
The problem is the currentSeconds and recordedDuration state values that I am getting. How come their values change between playAudio method which triggers the audio to be played and onPlaybackStatusUpdate which is the callback method?
When I output in the console their values in both methods this is what I obtain when I expect them to be the same:
In playAudio - currentSeconds: 0
In playAudio - recordedDuration: 4.5
In onPlaybackStatusUpdate - currentSeconds: 115.5
In onPlaybackStatusUpdate - recordedDuration: 0
And here is the code:
const AudioRecorder = useRef(new Audio.Recording());
const AudioPlayer = useRef(new Audio.Sound());
const timerMaxDuration = 120
const [currentSeconds, setCurrentSeconds] = useState<number>(timerMaxDuration);
const [recordedDuration, setRecordedDuration] = useState<number>(0);
const stopRecording = async () => {
try {
await AudioRecorder.current.stopAndUnloadAsync();
// To hear sound through speaker and not earpiece on iOS
await Audio.setAudioModeAsync({ allowsRecordingIOS: false });
const recordedURI = AudioRecorder.current.getURI();
SetRecordingURI(recordedURI)
AudioRecorder.current = new Audio.Recording();
send('STOP')
setRecordedDuration(+(timerMaxDuration - currentSeconds).toFixed(1)) // there is subtraction because during the recording there is a countdown from timerMaxDuration
setCurrentSeconds(0)
// Load audio after recording so that it is ready to be played
loadAudio(recordedURI)
} catch (error) {
console.log(error);
}
};
const loadAudio = async (recordedUri) => {
try {
const playerStatus = await AudioPlayer.current.getStatusAsync();
if (playerStatus.isLoaded === false) {
AudioPlayer.current.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate)
await AudioPlayer.current.loadAsync({ uri: recordedUri }, { progressUpdateIntervalMillis: 20 }, true)
}
} catch (error) {
console.log(error)
}
}
const playAudio = async () => {
console.log(`In playAudio - currentSeconds: ${currentSeconds}`)
console.log(`In playAudio - recordedDuration: ${recordedDuration}`)
try {
const playerStatus = await AudioPlayer.current.getStatusAsync();
if (playerStatus.isLoaded) {
if (playerStatus.isPlaying === false) {
AudioPlayer.current.playAsync();
send('PLAY')
}
}
} catch (error) {
console.log(error);
}
};
const onPlaybackStatusUpdate = playbackStatus => {
if (playbackStatus.isPlaying) {
console.log(`In onPlaybackStatusUpdate - currentSeconds: ${currentSeconds}`)
console.log(`In onPlaybackStatusUpdate - recordedDuration: ${recordedDuration}`)
if(currentSeconds >= recordedDuration){
stopAudio()
}
else{
setCurrentSeconds(+(playbackStatus.positionMillis / 1000).toFixed(1))
}
}
}
Ok so there was nothing wrong with the playback callback. The thing is that both the playback callback is an arrow functions which means that the only property value that will change inside the callback is the one of the argument playbackStatus, the other properties' values will remain the same as the time the function was created.
A walkaround in React is to use useEffect in the following way, which allows to access the state values currentSeconds and recordedDuration:
useEffect(() => {
if(currentSeconds >= recordedDuration)
stopAudio()
}, [currentSeconds]);
const onPlaybackStatusUpdate = playbackStatus => {
if (playbackStatus.isPlaying)
setCurrentSeconds(+(playbackStatus.positionMillis / 1000).toFixed(1))
}

how to fix black video streaming on ios - kurento

i have a video conference app built in nodejs and kurento.
when i connect my camera on desktop/Android everything is ok.
when i connect camera on iphone, i can see the shared video on iphone (locally) very well, but the camera on other devices (receiving devices) in the room stays black and doesn't show up.
my client code:
const videoConstraints = {};
videoConstraints.facingMode = 'environment';
const constraints = {
video: videoConstraints,
audio: false
};
receiveMediaLocal(token, 'webcam', socket.id, constraints)
setTimeout(() => {
iKurentoClient.sendMessage({ ...data, type: 'video', mode: 'webcam', id: 'connectMedia' })
}, 100)
function receiveMediaLocal(sender, mode, connId, constraints, mediaScreen = null) {
var participant = new Participant(this, sender, mode, connId);
if (!this.participants[sender]) this.participants[sender] = {};
this.participants[sender][mode] = participant;
var media = participant.getMediaElement();
var options = {
localVideo: media,
mediaConstraints: constraints,
onicecandidate: participant.onIceCandidate.bind(participant)
}
participant.rtcPeer = new kurentoUtils.WebRtcPeer.WebRtcPeerSendonly(options,
function (error) {
if (error) {
this.socket.emit("error",error);
return console.error(error);
}
this.generateOffer(participant.offerToReceiveMedia.bind(participant));
}
);
}
how can i fix this bug?
thank you.

React-Native-Image-Picker Auto video recording possible?

I'm a beginner at React Native.
I am trying to access a native(built-in) camera app on Android device.
I used React-Native-Image-Picker to open the camera app but I would like to record a video somehow automatically(?) I mean not using my finger.
I need codes that make it to record and stop the video.
(I don't mean to give me a code rather, please advise if it is even possible?)
Any help would be very appreciated.
Thank you!
It is possible.
Package: https://github.com/mrousavy/react-native-vision-camera
Review the API and Guide section to see how to start and stop recording programmatically.
They also show an example app that demonstrates different types of capture including video recording, ref: https://github.com/mrousavy/react-native-vision-camera/blob/28fc6a68a5744efc85b532a338e2ab1bc8fa45fe/example/src/views/CaptureButton.tsx
...
const onStoppedRecording = useCallback(() => {
isRecording.current = false;
cancelAnimation(recordingProgress);
console.log('stopped recording video!');
}, [recordingProgress]);
const stopRecording = useCallback(async () => {
try {
if (camera.current == null) throw new Error('Camera ref is null!');
console.log('calling stopRecording()...');
await camera.current.stopRecording();
console.log('called stopRecording()!');
} catch (e) {
console.error('failed to stop recording!', e);
}
}, [camera]);
const startRecording = useCallback(() => {
try {
if (camera.current == null) throw new Error('Camera ref is null!');
console.log('calling startRecording()...');
camera.current.startRecording({
flash: flash,
onRecordingError: (error) => {
console.error('Recording failed!', error);
onStoppedRecording();
},
onRecordingFinished: (video) => {
console.log(`Recording successfully finished! ${video.path}`);
onMediaCaptured(video, 'video');
onStoppedRecording();
},
});
// TODO: wait until startRecording returns to actually find out if the recording has successfully started
console.log('called startRecording()!');
isRecording.current = true;
} catch (e) {
console.error('failed to start recording!', e, 'camera');
}
}, [camera, flash, onMediaCaptured, onStoppedRecording]);
//#endregion
...

Clear the app data if disconnected from internet for more then 5min in react native

I want to clear the react native app data if my app is disconnected from internet for more than 5 min.
I am using react native NetInfo to check network connectivity status.
Saving the time when app disconnected and checking when it will reconnect to internet.
If interval is more than 5 min then I want to clear the app data.
My Code is:
class OfflineMessage extends PureComponent {
constructor(props) {
super(props);
this.state = {
isConnected: true
};
}
componentDidMount() {
NetInfo.addEventListener((state) => {
this.handleConnection(state.isConnected);
});
}
componentWillUnmount() {
NetInfo.removeEventListener((state) => {
this.handleConnection(state.isConnected);
});
}
handleConnection = (isConnected) => {
this.setState({ isConnected });
if(!isConnected){
this.startTimer();
} else {
this.checkElapsed();
}
};
startTimer = async () => {
try {
console.log('Internet disconnected at: ');
await AsyncStorage.setItem('time', JSON.stringify(Date.now()));
} catch (error) {
// console.log('Something went wrong', error);
}
}
checkElapsed = async () => {
try {
let startTime = await AsyncStorage.getItem('time');
if(startTime){
let endTime = Date.now();
const elapsedTime = Math.floor((endTime -JSON.parse(startTime))/1000);
if(elapsedTime > 5){
alert("5 min is completed.");
// Clear app data
}
console.log('Time elapsed'+ elapsedTime);
}
} catch (error) {
// console.log('Something went wrong', error);
}
}
Problem:
Both the methods startTimer and checkElapsed called whenever connectivity status changes.
What is wrong with this code.
if I modify given code as :
state = {
isConnected: true
};
componentDidMount() {
this.unsubscribeFromNetInfo = NetInfo.addEventListener((state) => {
this.handleConnection(state.isConnected);
});
}
componentWillUnmount() {
this.unsubscribeFromNetInfo();
}
handleConnection = (isConnected) => {
console.log(isConnected);
this.setState({ isConnected });
};
EventListener called multiple times and status changes frequently true false,true,false .
Now, you are handling the NetInfo subscription wrong, according to https://github.com/react-native-community/react-native-netinfo#usage
You would have to do:
componentDidMount() {
this.unsubscribeFromNetInfo = NetInfo.addEventListener(state => {
this.handleConnection(state.isConnected);
});
}
componentWillUnmount() {
this.unsubscribeFromNetInfo();
}
Also, if you want to check for 5 minutes use:
if (elapsedTime > 5 * 60)
as your conversion
Math.floor((endTime - JSON.parse(startTime)) / 1000)
converts it to seconds not minutes.
In the current state, your app will trigger almost everything as the code only checks for 5 seconds.
Otherwise, the logic that you implemented itself should be working :)