Hi,
I am using twilio-video1.14.2 in React. I followed the quick start. Initially I was getting an error that said "track.attach() is not a function.
I changed:
attachTracks(tracks, container) {
tracks.forEach(function(track) {
container.appendChild(track.attach());
});
}
attachParticipantTracks(participant, container) {
var tracks = Array.from(participant.tracks.values());
this.attachTracks(tracks, container);
}
room.participants.forEach(function(participant) {
log("Already in Room: '" + participant.identity + "'");
var previewContainer = document.getElementById('remote-media');
attachParticipantTracks(participant, previewContainer);
});
to
participant.tracks.forEach(publication => {
if (publication.isSubscribed) {
console.log('publication is subscribed..');
const track = publication.track;
this.refs.remoteMedia.appendChild(track.attach());
}
});
participant.on('trackSubscribed', track => {
this.refs.remoteMedia.appendChild(track.attach());
});
But now I get an error that says "track.detach() is not a function".
Here's the code where I detach the tracks:
participantDisconnected(participant) {
console.log(participant.tracks)
participant.tracks.forEach(track => {
const attachedElements = track.detach();
attachedElements.forEach(element => element.remove());
});
}
room.on('participantConnected',this.participantConnected);
room.on('participantDisconnected', this.participantDisconnected);
Where do you think I am going wrong? I am really struggling with this for a few days for some reason. Request you to please assist me in setting up the video chat. I will be really grateful. Thank you!
@smashingpixelsindia ,
Thanks for writing in with your issue. If you are using twilio-video.[email protected], then participant.tracks is a collection of RemoteTracks, which have the attach and detach methods. You should be able to use them as specified in the QuickStart.
From the errors that you are seeing, it looks like you are using twilio-vide.[email protected]*, where participant.tracks is a collection of RemoteTrackPublications. That is the reason you are not seeing the attach and detach methods.
For twilio-video.js 2.x, the quickstart code can be found here. Please let me know if this works for you.
Thanks,
Manjesh Malavalli
JSDK Team
@manjeshbhargav,
So, trackPublication.detach() is not available anymore and according to the quickstart trackPublication.track.detach() should work, but in Beta 5 a TrackPublication does not have a track property? So how can I detach the HTML elements for the remote tracks?
@manjeshbhargav
I still having these problem... firstly i using this version //media.twiliocdn.com/sdk/js/video/releases/1.14.0/twilio-video.js and everthing working fine, but suddenly the remote video stopped showing without any error, the audio was working but remote video was not working.
Then i tried https://media.twiliocdn.com/sdk/js/video/releases/2.0.0-beta5/twilio-video.min.js this version
it throw track.attach() is not a function. I also tried your updated quickstart but still throws the same error track.attach() is not a function
Can you please help out here, will be very appreciating
Thanks in advance
@Govind13100
I developed a video chat application that works with version 1.15 (using the new features) and also with 2.0.0-beta5 (which by the way seems to be pretty stable). When creating local tracks using video.createLocalTracks, these tracks have the attach method (because they are of type LocalAudioTrack or LocalVideoTrack). When handling the Room event trackSubscribed, the first parameter is either a RemoteAudioTrack or a RemoteVideo Track. These also have the attach method.
attachParticipantTracks looks a bit different in my case:
attachParticipantTracks(participant, container, isLocal) {
var tracks = this.getTracks(participant);
this.attachTracks(tracks, container, isLocal);
}
getTracks(participant) {
return Array.from(participant.tracks.values()).filter(function (publication) {
return publication.track;
}).map(function (publication) {
return publication.track;
});
}
getTracks is the trick here. It reads the tracks from the track publications of the participant.
hi @freeboarder42
Thanks for your answer that really helps. But now i am facing the detach() problem same as attach
do you have any solution for this ?
Hi @Govind13100
Here is the relevant code:
roomJoined(room) {
...
room.on('participantDisconnected', this.onParticipantDisconnected);
room.on('trackUnsubscribed', this.onParticipantUnpublishedTrack);
...
}
onParticipantDisconnected(participant, error) {
// When a (remote) participant disconnects, detach the assiciated tracks
this.detachParticipantTracks(participant);
}
onParticipantUnpublishedTrack(track, trackPublication) {
this.detachTracks([track]);
}
detachParticipantTracks(participant) {
var tracks = this.getTracks(participant);
this.detachTracks(tracks);
}
detachTracks(tracks) {
for (let track of tracks) {
const htmlElements = track.detach();
for (let htmlElement of htmlElements) {
htmlElement.remove();
}
}
}
Please note that detachParticipantTracks uses the getTracks function I put in my last post.
@freeboarder42 Hi, thanks for your help above.
When dealing with local tracks the updated getTracks function worked well, However when trying remote tracks it always returns null. I notice you are doing something with your isLocal variable. Are you able to share?
Thanks in adavnce
Charlie
I'm seeing similar behaviour
It's weird - if I do console.log(publication, publication.track), in the log, the publication will have a track property that is a non-null value, but then when it logs the track itself, it is null.
@Govind13100
I had worked with v1.15 and currently v2.0.0-beta5 (successfully upgrade after reviewing the code of QuickStart app), can you put your code snippet so we could better figure out what is the issue.
hi @kaitlynbrown
We have managed to fix this by adding the following code in the room.on('participantConnected') function.
room.on('participantConnected', function (participant) {
$scope.log("Joining: '" + participant.identity + "'");
participant.tracks.forEach(publication => {
if (publication.isSubscribed) {
const track = publication.track;
document.getElementById('remote-media-div').appendChild(track.attach());
}
});
participant.on('trackSubscribed', function (track) {
document.getElementById('remote-media-div').appendChild(track.attach());
});
});
Hi @freeboarder42
Thanks for giving solution for attach() is undefined issue.
hi @freeboarder42
getTracks() method works like charm.Thanks you for the solution.
Hi @jadavpalak , @smashingpixelsindia ,
I'm going to close this issue since it looks like you got all the answers you needed. @freeboarder42 , thanks for helping out with providing code samples.
Thanks,
Manjesh Malavalli
JSDK Team
Hi @Govind13100
Here is the relevant code:
roomJoined(room) { ... room.on('participantDisconnected', this.onParticipantDisconnected); room.on('trackUnsubscribed', this.onParticipantUnpublishedTrack); ... } onParticipantDisconnected(participant, error) { // When a (remote) participant disconnects, detach the assiciated tracks this.detachParticipantTracks(participant); } onParticipantUnpublishedTrack(track, trackPublication) { this.detachTracks([track]); } detachParticipantTracks(participant) { var tracks = this.getTracks(participant); this.detachTracks(tracks); } detachTracks(tracks) { for (let track of tracks) { const htmlElements = track.detach(); for (let htmlElement of htmlElements) { htmlElement.remove(); } } }Please note that
detachParticipantTracksuses thegetTracksfunction I put in my last post.
Hi @freeboarder42,
Thanks for your help so far. I'm getting errors from the getTracks method.
this.getTracks is not a function. (In 'this.getTracks(participant)', 'this.getTracks' is undefined)
I'm not sure why this is the case. If you have any ideas please let me know.
I got this track.attach()/track.detach() error even though local + remote video/audio seemed to be working fine.
I discovered it was because one of the tracks it was trying to .attach()/.detach() was the data track.
Just wrapping the attach/detach with if (track.kind !== 'data') { ... } fixed it for me. Hope this helps someone else.
@corysimmons That's brilliant! Problem solved!! Thank you!!
Most helpful comment
@Govind13100
I developed a video chat application that works with version 1.15 (using the new features) and also with 2.0.0-beta5 (which by the way seems to be pretty stable). When creating local tracks using
video.createLocalTracks, these tracks have theattachmethod (because they are of typeLocalAudioTrackorLocalVideoTrack). When handling theRoomeventtrackSubscribed, the first parameter is either aRemoteAudioTrackor aRemoteVideoTrack. These also have theattachmethod.attachParticipantTrackslooks a bit different in my case:getTracksis the trick here. It reads the tracks from the track publications of the participant.