Video Streams show Black Screen sometimes (Android)
See original GitHub issueBug report
- Reproduced on:
- iOS
Description
This only happens sometimes, and I can’t find how to make it consistent. But it is a critical bug for myself. When call comes on Android device, sometimes both Remote and Local Stream show Black screen and I can’t see any live video feed.
I use React Native CallKeep for handling calls.
Steps to Reproduce
- Call Android Device
- Display Incoming Call UI
- Accept Call and App is sent back to foreground
- See buttons and black screen instead of video stream (IE RTCView is displaying Black Video screen)
Versions
- ConnectyCube: Latest
- CallKeep: Latest
- React Native: 0.63.2
- Phone model: Android 7 Samsung S6
Code
const CallControl = ({ route }: { route: any }) => {
const initSession = {
ID: '',
initiatorID: 0,
currentUserID: 0,
opponentsIDs: [],
getUserMedia: () => {},
accept: () => {},
call: () => {},
stop: () => {},
mute: () => {},
unmute: () => {},
reject: () => {},
};
const initExtension = { busy: false };
const sess = useRef<Session>(initSession);
const ext = useRef<Extension>(initExtension);
const callId = useRef<string>('');
const currentUser = route?.params?.currentUser || {};
const [localStream, setLocalStreams] = useState<any>([]);
const [remoteStreams, setRemoteStreams] = useStateCallback<
[] | Array<Stream>
>([]);
const [selectedUserId, setSelectedUser] = useState<null | number>(null);
const [isAudioMuted, setIsAudioMuted] = useState(false);
const [isFrontCamera, setIsFrontCamera] = useState(true);
const cam = true;
const reset = async () => {
const id = oneTimeId();
RNCallKeep.endCall(id);
await ConnectyCube.videochat.clearSession(sess.current.ID);
RNCallKeep.endAllCalls();
InCallManager.stop();
setRemoteStreams([]);
setLocalStreams([]);
setSelectedUser(null);
setIsAudioMuted(false);
setIsFrontCamera(true);
sess.current = initSession;
ext.current = initExtension;
callId.current = '';
};
const oneTimeId = () => {
callId.current = callId.current || uuid();
return callId.current;
};
// Start/Stop onPress call handlers
const startCall = async () => {
if (!selectedUserId) {
return;
}
const t = ConnectyCube.videochat.CallType.VIDEO; // AUDIO is also possible
sess.current = ConnectyCube.videochat.createNewSession([selectedUserId], t);
const stream = await sess.current?.getUserMedia?.(MEDIA_OPTIONS);
await sess.current?.call({});
setLocalStreams([{ userId: 'localStream', stream }]);
setRemoteStreams([{ userId: selectedUserId, stream: null }]);
if (isIOS) {
const id = oneTimeId();
const name = users.find(u => u.id === selectedUserId)?.name || '';
RNCallKeep.startCall(id, name, name, 'generic', cam);
}
};
const stopCall = async () => {
await sess.current?.stop?.({});
await reset();
};
// CallKeep button actions
const acceptCall = async () => {
const id = oneTimeId();
RNCallKeep.setCurrentCallActive(id);
const stream = await sess.current?.getUserMedia?.(MEDIA_OPTIONS);
await sess.current?.accept?.({});
setLocalStreams([{ userId: 'localStream', stream }]);
setRemoteStreams([{ userId: selectedUserId, stream: null }]);
};
const rejectCall = async () => {
await sess.current?.reject?.(ext.current);
await reset();
};
// ConnectyCall Listeners
const onCallListener: Listener = async (session, _userId, extension) => {
ext.current = extension || initExtension;
sess.current = session || initSession;
const name =
users.find(u => u.id === sess?.current?.initiatorID)?.name || '';
const id = oneTimeId();
RNCallKeep.displayIncomingCall(id, name, name, 'generic', cam);
};
const onAcceptCallListener: Listener = async (session, _, extension) => {
ext.current = extension || initExtension;
sess.current = session || initSession;
};
const onRemoteStreamListener = async (
_session: Session,
userId: number,
stream: Stream
) =>
setRemoteStreams([...remoteStreams, { userId, stream }], () => {
InCallManager.start({ media: 'video', auto: false });
InCallManager.setSpeakerphoneOn(true);
RNCallKeep.backToForeground();
});
const onRejectCallListener = async () => {
await reset();
};
const onStopCallListener = async () => {
await reset();
};
const onUserNotAnswerListener = async () => {
if (!remoteStreams[0]) {
await reset();
}
};
// Init
const initializeConnectyCube = () => {
ConnectyCube.videochat.onCallListener = onCallListener;
ConnectyCube.videochat.onAcceptCallListener = onAcceptCallListener;
ConnectyCube.videochat.onRemoteStreamListener = onRemoteStreamListener;
ConnectyCube.videochat.onRejectCallListener = onRejectCallListener;
ConnectyCube.videochat.onStopCallListener = onStopCallListener;
ConnectyCube.videochat.onUserNotAnswerListener = onUserNotAnswerListener;
};
const initializeCallKeep = async () => {
await RNCallKeep.setup(SETUP_OPTIONS);
RNCallKeep.setAvailable(true);
RNCallKeep.addEventListener('answerCall', acceptCall);
RNCallKeep.addEventListener('endCall', rejectCall);
};
const cleanup = () => {
RNCallKeep.removeEventListener('answerCall');
RNCallKeep.removeEventListener('endCall');
stopCall();
};
useEffect(() => {
initializeConnectyCube();
initializeCallKeep();
return cleanup;
}, []);
// Actions
const toggleMute = () => {
const mute = !isAudioMuted;
setIsAudioMuted(mute);
mute ? sess.current?.mute?.('audio') : sess.current?.unmute?.('audio');
};
const toggleCamera = () => {
setIsFrontCamera(!isFrontCamera);
localStream[0]?.stream
?.getVideoTracks?.()
.forEach((track: Track) => track._switchCamera());
};
// Buttons
const renderCallStartStopButton = () => (
<TouchableOpacity
style={[
styles.buttonContainer,
remoteStreams[0] ? styles.buttonCallEnd : styles.buttonCall,
]}
onPress={remoteStreams[0] ? stopCall : startCall}>
<MaterialIcon
name={remoteStreams[0] ? 'call-end' : 'call'}
size={32}
color='white'
/>
</TouchableOpacity>
);
const renderMuteButton = () => (
<TouchableOpacity
style={[styles.buttonContainer, styles.buttonMute]}
onPress={toggleMute}>
<MaterialIcon
name={isAudioMuted ? 'mic-off' : 'mic'}
size={32}
color='white'
/>
</TouchableOpacity>
);
const renderSwitchVideoSourceButton = () => (
<TouchableOpacity
style={[styles.buttonContainer, styles.buttonSwitch]}
onPress={toggleCamera}>
<MaterialIcon
name={isFrontCamera ? 'camera-rear' : 'camera-front'}
size={32}
color='white'
/>
</TouchableOpacity>
);
return (
<SafeAreaView style={{ flex: 1, backgroundColor: 'black' }}>
<StatusBar backgroundColor='black' barStyle='light-content' />
{remoteStreams[0] ? (
<View style={styles.inColumn}>
<VideoScreen
mirror={false}
stream={remoteStreams?.[0]?.stream}
userId={remoteStreams?.[0]?.userId}
/>
<VideoScreen
mirror={isFrontCamera}
stream={localStream?.[0]?.stream}
userId={localStream?.[0]?.userId}
/>
</View>
) : (
<UsersSelect
currentUser={currentUser}
selectedUserId={selectedUserId}
setSelectedUser={setSelectedUser}
/>
)}
<SafeAreaView style={styles.container}>
<View style={styles.toolBarItem}>
{remoteStreams[0] && renderMuteButton()}
</View>
{(selectedUserId || remoteStreams[0]) && (
<View style={styles.toolBarItem}>{renderCallStartStopButton()}</View>
)}
<View style={styles.toolBarItem}>
{remoteStreams[0] && localStream && renderSwitchVideoSourceButton()}
</View>
</SafeAreaView>
</SafeAreaView>
);
};
Issue Analytics
- State:
- Created 3 years ago
- Comments:33 (12 by maintainers)
Top Results From Across the Web
[SOLVED] Screen Goes Black When Watching Videos Android
If the screen goes black when watching videos Android”, possible causes include ad-blocking plugins, browser, network and app problems.
Read more >Top 8 Ways to Fix YouTube Black Screen Issue on Android TV
Is the YouTube app showing a black screen on your Android TV? Check out these top 8 ways to get rid of the...
Read more >Resolve Black Screen Issue When Play Videos
Sometimes, while watching a video on a media player or YouTube, you tend to have a black screen, but at the back, the...
Read more >Black screen when returning to video playback activity in ...
A black screen is shown instead of the video. Does anyone have a workaround or solution for this issue.
Read more >How can I fix black screen issues? - Agora Documentation
Check the camera hardware. Start the built-in video camera to test the recording function. Check if the camera access permission is enabled. Both...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Hi @ccvlad,
Thanks for the reply. I’m sorry I didn’t see this was for android specifically.
However I managed to get it working eventually. For me the key was to configure and initialize the audiosession of the videosession. When I didn’t set this specifically, I ended up with the occasional black screen for one user… When I set the audiosession and configured it for the videochat, everything just runs smoothly! I don’t know if this is any help, but just thought I’d put it out here. Maybe it’s not the video itself that it causing the problem, but setting the correct audio device for the localstream. Good luck in solving this problem! And thanks again for the reply.
Closed due to inactivity. Please create a new issue if needed.