Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Push to talk #690

Closed
wants to merge 2 commits into from
Closed

Conversation

aviraldg
Copy link
Contributor

No description provided.

@matrixbot
Copy link
Member

Can one of the admins verify this patch?

@dbkr
Copy link
Member

dbkr commented Feb 13, 2017

@matrixbot test this please

package.json Outdated
@@ -62,6 +62,7 @@
"linkifyjs": "^2.1.3",
"lodash": "^4.13.1",
"matrix-js-sdk": "matrix-org/matrix-js-sdk#develop",
"msr": "^1.3.4",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this basically switches between getusermedia and web audio which means we get Safari support? I'm a little hesitant to grow the bundle size by another 22KB.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, looks like you still need to call getUserMedia manually, so it won't make it automatically work in Safari.

});
} else {
try {
const mediaStream = await navigator.mediaDevices.getUserMedia({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably check for this and display a "not supported" message rather than just the normal, "failed to start recording".

onRecordClicked = async () => {
if(this.state.recording && this.mediaStream) {
this.recorder.stop();
window.ConcatenateBlobs(this.blobs, this.blobs[0].type, (blob) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ew. I dislike this library that pulls in the completely non-commonjs ConcatenateBlobs which just shoves itself on the window object, for one fairly simple function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hate it too, but used it for a quick first version. I'll get rid of it.

if(this.state.recording && this.mediaStream) {
this.recorder.stop();
window.ConcatenateBlobs(this.blobs, this.blobs[0].type, (blob) => {
console.log(blob);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably don't want to leave this in

onUserMediaSuccess = (mediaStream: MediaStream) => {
this.mediaStream = mediaStream;
this.recorder = new MediaStreamRecorder(this.mediaStream);
this.recorder.recorderType = class extends MediaStreamRecorder.StereoAudioRecorder {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this were a named class you could call it MonoAudioRecorder which might make it more obvious what's going on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't need this once that library's gone.

render() {
const TintableSvg = sdk.getComponent("elements.TintableSvg");
return (
<div key="controls_ptt" className="mx_MessageComposer_voicecall"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be an AccessibleButton nowadays

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. I'll check for other places where it's used -- MessageComposerInput itself does not seem to have been updated.

return (
<span className="mx_MAudioBody">
<audio src={contentUrl} controls />
<audio src={contentUrl} controls autoPlay={shouldAutoPlay} />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can allow auto-playing audio globally: there's too much scope for abuse. This would also presumably play all files as you scrolled past them in the backlog.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, but I'd prefer to keep this simple and iterate on the logic rather than have this PR stuck forever (given the demand.)

What I had in mind:

  • Only autoplay if the current user has also sent a PTT message in the same room (so you need to send one first to have others' messages autoplay to you)
  • Play automatically when you receive a message (and the above condition is satisfied)
  • Queue up newer messages as they come in, if there's something already playing

(this can't work with the autocomplete attribute though)

Also, while I'm currently reusing the microphone icon, it might be worth considering if we want to change it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would also presumably play all files as you scrolled past them in the backlog

Wouldn't this also play sounds as they get rendered. So when I log in, or switch rooms? That sounds quite terrifying.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps MAY autoplay?

@dbkr
Copy link
Member

dbkr commented Feb 13, 2017

Generally looking nice though, lots of people asking for this feature! Unsure why babel dislikes your flow syntax.

Also, some usability enhancements
@aviraldg aviraldg requested a review from dbkr February 16, 2017 14:29
import Modal from '../../../Modal';
import ErrorDialog from '../dialogs/ErrorDialog';

export default class AudioRecorder extends React.Component {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 space indents please, for consistency with the rest of the project

if(!navigator.mediaDevices || !MediaRecorder) {
Modal.createDialog(ErrorDialog, {
description: `Sorry, but the features required for push
to talk messages are not supported by your browser`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it also has defaults for those properties.

onUserMediaSuccess = (mediaStream: MediaStream) => {
this.mediaStream = mediaStream;

this.mediaRecorder = new MediaRecorder(mediaStream);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving out the options parameter, in particular mimeType, seems unwise, given the default is likely to vary between browsers. What format are we expecting here? Bear in mind we'll need to spec this so it can be implemented cross-client, we'll need to nail down what audio formats clients should expect.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is the option to check for supported mimeTypes: MediaRecorder.isTypeSupported(). Expected is "audio/webm;codecs=opus" for Chrome and "audio/ogg;codecs=opus" for Firefox. (Keep in mind that Safari doesn't support MediaRecorder.) Seems like Firefox can only record ogg audio and Chrome only WebM audio (see https://stackoverflow.com/questions/35466078/specifying-codecs-with-mediarecorder). Both browser can play both file types though, so that's not a problem.


onMediaRecorderStop = () => {
// Chrome gives us video/webm even though we've requested audio
// for some reason. The data's still just audio though.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be more sensible if given a mimeType in the MediaRecorder constructor

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like Chrome only supports recording WebM, see https://stackoverflow.com/questions/41739837/all-mime-types-supported-by-mediarecorder-in-firefox-and-chrome and links in the answer. Is that important?

const AccessibleButton = sdk.getComponent("elements.AccessibleButton");

const className = classNames('mx_MessageComposer_ptt', {
'mx_MessageComposer_ptt--recording': this.state.recording,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the -- syntax?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a habit I got from using getbem.com on some of my projects but will happily get rid of if it's an issue

@aviraldg
Copy link
Contributor Author

aviraldg commented Feb 18, 2017 via email

@Half-Shot
Copy link
Contributor

@aviraldg Apologies, GH wasn't doing a very good job of hiding old code :/

@dtygel
Copy link
Contributor

dtygel commented May 4, 2017

@aviraldg Have you stopped developing this feature?

@aviraldg
Copy link
Contributor Author

aviraldg commented May 4, 2017 via email

@superdump
Copy link
Contributor

As a note, the last time I checked (around the beginning of 2017), format support with the MediaRecorder API on different browsers varies significantly. Chrome would produce opus/webm and Firefox opus/ogg. I think there were issues with playback too as well as the MediaRecorder API implementations not always giving the errors they were supposed to meaning that you had to test, verify and tip-toe around how the browsers actually behaved. I would definitely expect the situation to have improved but I'm not certain of it. Testing would be needed. 😄

@dtygel
Copy link
Contributor

dtygel commented Aug 29, 2017

What does telegram web and whatsapp web use for recording and reproducing audio? It seems to work without issues...

@ghost
Copy link

ghost commented Aug 29, 2017

The basic feature works as-is, but is blocked on speccing the allowed formats (something I haven't had time to do yet.) If you are interested in seeing this merged, discussing that with the team and proposing a change to the spec for it would be a good start.

Where do you discuss things with the team? I did some research and suggest the Opus codec. It's state of the art and freely licensed. Chrome and Firefox support it, but Safari doesn't. Is that an issue? Chrome records WebM files and Firefox .ogg files, but both browsers can play both formats. What more information is required?

@dtygel
Copy link
Contributor

dtygel commented Sep 2, 2017

@WorldCodeCentral , discussions on riot development happen in riot-dev room: https://riot.im/app/#/room/#riot-dev:matrix.org

@jryans
Copy link
Collaborator

jryans commented Jul 31, 2019

Thanks for making this contribution a while back. Since the code base has changed since this was opened, it no longer applies cleanly, and I don't think there's a need to keep it open in this state, as we can always find the code here again if needed. If you are still interested in pursuing this feature, please discuss with us in #riot-dev:matrix.org to find a good approach forward.

@jryans jryans closed this Jul 31, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants