react native live streaming - stream

I want to make a react-native app that is able to:
show live streaming
upload live streaming
save streaming
I have a rtmp url and a playback url. I tried to achieve my goals using "react-native-video-stream" however stream doesn't start and there is no apparent errors.
How can I live stream videos in my app and which library should be used.
Please provide an example / demo app which does live streaming

I found one simple platform called mux to create live stream, upload and save it to play later. react-native-nomediaclient will help you to stream your video. On other side you can just user react-native-video to play the stream.
Here is the blog of whole process.
There are others also platform to create stream. But, the point is that you can stream from any of them using react-native-nomediaclient library.
Update:
Here is the nomediaclient configuration to create live stream using mux :
<NodeCameraView
style={styles.nodeCameraView}
ref={(vb) => { this.vb = vb }}
outputUrl = {`rtmp://live.mux.com/app/${this.state.streamId}`}
camera={{ cameraId: 0, cameraFrontMirror: true }}
audio={{ bitrate: 32000, profile: 1, samplerate: 44100 }}
video={{
preset: 4,
bitrate: 2000000,
profile: 2,
fps: 30,
videoFrontMirror: false
}}
autopreview={true}
/>
To get streamId :
createLive = async () => {
const auth = {
username: MUX_ACCESS_TOKEN,
password: MUX_SECRET
};
const param = { "reduced_latency": true, "playback_policy": "public", "new_asset_settings": { "playback_policy": "public" } }
const res = await axios.post('https://api.mux.com/video/v1/live-streams', param, { auth: auth }).catch((error) => {
throw error;
});
console.log(res.data.data);
const data = res.data.data;
this.setState({
streamId: data.stream_key
});
}
Update 2
I have also find another platform which is better than Mux called Bambuser. It provide easiest installation process for your react native application. It also has many advance features like, you can stream on multiple platform at a time. It provides high quality audio and video streaming with minimum lag time. I have used in my app and it's working without any issues.
Here is the library that you can use with your react-native application :
react-native-bambuser-player : Which allows you to play stream in your user side app.
react-native-bambuser-broadcaster : Using this library you create your broadcaster app to stream video for you user side app.
Follow the installation steps properly and you good to go.
Also if you don't want to build your broadcaster app, they also provide their own app to create live stream. It's has most of all feature that should be in broadcast app. You have to just login in app and it start stream for your player app.
Bambuser (Android)
Bambuser (iOS)
It also gives 14 days free trial to testing.
Sample Code
import Bambuser player :
import RNBambuserPlayer from 'react-native-bambuser-player';
Declare const for your credential :
const BambuserApplicationIds = {
android: 'ANDROID_APPLICATION_ID', // your bambuser android application id
ios: 'IOS_APPLICATION_ID' // your bambuser ios application id
}
const BambuserResourceUri = 'YOUR_BAMBUSER_RESOURCE_URI';
Here is the detail about how you can get applicationId and resourceUri.
render the Bambuser Player view :
<RNBambuserPlayer
style={{ flex: 1 }}
ref={ref => {
this.myPlayerRef = ref;
}}
applicationId={
Platform.OS === 'ios'
? BambuserApplicationIds.ios
: BambuserApplicationIds.android
}
requiredBroadcastState={
RNBambuserPlayer.REQUIRED_BROADCAST_STATE.LIVE
}
videoScaleMode={RNBambuserPlayer.VIDEO_SCALE_MODE.ASPECT_FILL}
resourceUri={BambuserResourceUri}
onTotalViewerCountUpdate={viewer => {
this.setState({ views: viewer }); // handle views update here
}}
onPlaying={() => {
// code to handle when playing stream
}}
onPlaybackError={error => {
// handle when some error occures
Alert.alert('Error', error.message);
}}
onPlaybackComplete={() => {
// this method called when stream is complete. Write some code to handle stream complete like :
this.setState({ isPlaying: false, isLiveEnded: true }, () => {
this.props.navigation.setParams({ isLive: false });
});
}}
onStopped={() => {
// called when stream stops.
this.setState({ isPlaying: false }, () => {
this.props.navigation.setParams({ isLive: false });
});
}}
/>
You can read here more about props.

Related

Added info cards are not visible on Youtube video

I have updated Youtube video by using Youtube data api.I got successful response from api. I have updated my video title and also added cards with api. I can see title was updated instantly but not able to find added cards on Youtube video.
I have tried below given code with node.js api.I have not received any errors and api call was success. But video title was updated successfully from same api and cards are not visible on video
async function addInfoCardsToVideo(videoId) {
try {
// First, retrieve the video's current metadata
const video = await youtube.videos.list({
part: 'snippet',
id: 'myexistingvideoid', // This is my existing Youtube video id
});
// Next, construct the new metadata object with the info card data
const infoCard = {
kind: 'youtube#video',
videoId: videoId,
card: {
teaser: {
startTimeMs: 10000, // The time in milliseconds where the teaser begins
endTimeMs: 30000, // The time in milliseconds where the teaser ends
},
cards: [
{
teaserTitle: 'Info Card Title',
teaserDurationMs: 5000, // The duration of the teaser in milliseconds
teaserStartTimeMs: 20000, // The time in milliseconds where the teaser should be displayed
type: 'video',
videoId: 'othervideoid', // The video ID for the video you want to link to
},
],
},
};
// Update the video's metadata to add the info card
const update = await youtube.videos.update({
part: 'snippet',
resource: {
id: videoId,
snippet: {
...video.data.items[0].snippet,
localized: {
...video.data.items[0].snippet.localized,
},
cards: infoCard,
title:'updated video title'
},
},
});
console.log(`Successfully updated video: ${videoId}`);
} catch (err) {
console.error(`Error updating video: ${err}`);
}
}
addInfoCardsToVideo('myexistingvideoid') //passing my existing Youtube video id ]
Kindly help

Dominant speaker not working properly | Twilio In Laravel

I have already implemented the Twilio dominant Speaker related code the code in bellow .
In my code problem is in dominantSpeakerChanged function when any user added in room ,unmute or mute the audio and mute unmute video then i am getting the response. But not getting any response when some one is talking.
when any user talk during the call at that time function is not called, i need when any user speak in call then give indication who is speaking like bellow image.
Image Link -
https://github.com/Soumojit1995/Issue/blob/main/Google_Meet_QA.max-2000x2000.jpg
Code -
var connectOptions = {
name: roomName,
// logLevel: 'debug',
_useTwilioConnection: true,
audio: { name: 'microphone' },
video: { name: 'camera' },
dominantSpeaker: true
};
if (previewTracks) {
connectOptions.tracks = previewTracks;
}
// Join the Room with the token from the server and the
// LocalParticipant's Tracks.
Video.connect(data.token, connectOptions).then(roomJoined, function(error) {
});
After call Video.connect function call roomJoined function in this function use dominantSpeakerChanged function.
// Successfully connected!
function roomJoined(room) {
room.on('dominantSpeakerChanged', participant => {
console.log('The new dominant speaker in the Room is:', participant);
});
}

Twillio Video and JavaScript: Changing Webcam

I am trying to implement a webchat with Twilio Programmable Video and its Javascript SDK.
So far I have managed to create a Room (in the backend) and connect the current user to the room.
The video is streamed from the local webcam (on a PC) to a div which is called 'remote-media-div'.
When the user is connected and video is seen on the screen, Twilio inserts a tag and a tag into remote-media-div
I would like to let the users choose the camera if they have more than one. I get the list of cameras and show it in a drop-down. When I select the webcam I run the below code to switch the stream to a newly selected camera. The second webcam's recording light is turned on but the video is still being received from the previous camera. What am I doing wrong?
let currentStream = null;
$.ajax({
url: `/operations/Room/Create`,
type: 'POST',
contentType: "application/json",
success: function (result) {
var roomName = result.room.name;
var token = result.room.token;
Twilio.Video.connect(token,
{
name: `${roomName}`,
audio: true,
maxAudioBitrate: 16000,
video: { height: 1000, frameRate: 24, width: 1000 },
networkQuality: {local:1, remote: 1}
}
).then(function(room) {
currentStream= room.stream;
navigator.mediaDevices.enumerateDevices().then(gotDevices);
const localParticipant = room.localParticipant;
localParticipant.tracks.forEach(publication => {
const track = publication.track;
document.getElementById('remote-media-div').appendChild(track.attach());
});
}, function(error) {
console.error('Unable to connect to Room: ' + error.message);
});
},
error: function (error) {
console.log(error);
}
});
When the drop-down changes, I switch the media stream.
function stopMediaTracks(stream) {
stream.getTracks().forEach(track => {
track.stop();
});
}
var cameraId = 1; // new Camera Id
const videoConstraints = {};
videoConstraints.deviceId = { exact:cameraId };
const constraints = {
video: videoConstraints,
audio: true
};
if (currentStream) {
stopMediaTracks(currentStream);
}
debugger;
const video = document.getElementsByTagName('video');
navigator.mediaDevices
.getUserMedia(constraints)
.then(stream => {
currentStream = stream;
video.srcObject = stream;
return navigator.mediaDevices.enumerateDevices();
})
.catch(error => {
console.error(error);
});
This code, as I said, does not turn the previous camera off. And the video (my own picture) keeps coming from the previous camera although the new camera is on too.
I have looked at the sample codes on GitHub and I don't seem to have done it incorrectly.
Twilio developer evangelist here.
I think I know the sample code on GitHub that you are looking at (I think it's mine 😉) but you have missed that there is a sample Video Chat available there too.
First, I can tell you that you are not seeing the first stream end because you are trying to set currentStream to room.stream which doesn't exist. This means stopMediaTracks is never called.
Secondly, you are not applying the new video stream to the room, so it won't be seen by other participants in the call. You need to turn the new camera stream into a LocalVideoTrack and then publish the track to the room.
I recommend you read through this blog post on changing cameras during a Twilio video call and check this example code for changing a camera during a Twilio Video call.

Expo AV audio not playing on iOS/ iPhone

I have used Expo AV and developed a screen in my app to play audio files fetched from my server. It works fine on Android, but doesn't play anything on iPhone.
When I play a button to play the audio which loads and plays the file
soundObject.loadAsync({ uri: this.state.file });
soundObject.playAsync();
It returns an error:
This media format is not supported. - The AVPlayerItem instance has failed with the error code -11828 and domain "AVFoundationErrorDomain".
Here is my code that loads and plays the audio :
async loadAudio() {
soundObject = new Audio.Sound();
try {
await soundObject.loadAsync({ uri: this.state.file });
console.log("File loaded: " + this.state.file);
} catch (error) {
console.log(error);
}
}
async playAudio() {
if (!this.state.isPlayingAudio) {
try {
await soundObject.playAsync();
} catch (error) {
console.log(error);
}
else {
soundObject.pauseAsync();
}
}
I have tried changing the audio format to m4a, wav, caf while recording and fetching the file but that did not help
I'm running the app on iPhone 7 plus, iOS 14.2
Any suggestions/ fixes, please? Thanks in advance
You're calling loadAsync improperly.
The call should look like this:
await Audio.Sound.createAsync(
{ uri: this.state.file },
{ shouldPlay: true }
);
I'm passing the uri object and a second argument {shouldPlay: true} to the loadAsync method.
This plays my mp3 files from amazon server s3
await Audio.Sound.loadAsync( { uri: this.state.file }, { shouldPlay: true } )
Please add this method before playing soundd view "expo-av"
const enableAudio = async () => {
await Audio.setAudioModeAsync({
playsInSilentModeIOS: true,
staysActiveInBackground: false,
interruptionModeAndroid: INTERRUPTION_MODE_ANDROID_DO_NOT_MIX,
shouldDuckAndroid: false,
})
I was on Expo 44, downgrading to Expo 43 did the trick. Run expo upgrade 43.

Programmable Video twilio: How to reuse mediaStream

Let say i already have acquired the stream using
var stream ;
navigator.getUserMedia({ audio: true, video: true}, function(mediastream) {
stream=mediastream;
});
Now how can i use stream when connecting to a room, I dont want Twilio to call getUserMedia again in createLocalTracks when i call Twilio.Video.connect api. ?
Twilio developer evangelist here.
You can use the stream you already collected. You just have to pass the tracks as an option to Video.connect with the tracks key. There is an example in the documentation which I have reproduced below:
var Video = require('twilio-video');
var token = getAccessToken();
// Connect with media acquired using getUserMedia()
navigator.mediaDevices.getUserMedia({
audio: true,
video: true
}).then(function(mediaStream) {
return Video.connect(token, {
name: 'my-cool-room',
tracks: mediaStream.getTracks()
});
}).then(function(room) {
room.on('participantConnected', function(participant) {
console.log(participant.identity + ' has connected');
});
room.once('disconnected', function() {
console.log('You left the Room:', room.name);
});
});

Resources