# Media

## Getting Streams

#### Get Camera

```javascript
function startCamera() {
  function getCameraStream(stream) {
    console.log("Starting Camera");
    stream.onended = () => {
      console.log("Camera Stream ended.");
    };
    setCamStream(stream);
  }

  navigator.mediaDevices
    .getUserMedia({
    audio: false,
    video: true
  })
    .then(getCameraStream)
    .catch(err => {
    getUserMediaError(err);
    setCameraError(err);
  });
}
```

#### Get Audio

Do it seperate then add as a track to your stream, might be able to just say audio true, but mac makes it jank or something idk

```javascript
function startAudio() {
  function getAudio(stream) {
    console.log("Starting Audio Stream");
    stream.onended = () => {
      console.log("Audio Stream ended.");
    };
    setAudioStream(stream);

  navigator.mediaDevices
    .getUserMedia({ audio: true, video: false })
    .then(getAudio)
    .catch(getUserMediaError);
  }
```

#### Get Screen

```javascript
function startCapture(displayMediaOptions) {
 let captureStream = null;

 return navigator.mediaDevices.getDisplayMedia(displayMediaOptions)
    .catch(err => { console.error("Error:" + err); return null; });
}
```

#### Checking Permissions

```javascript
const audioP = await navigator.permissions.query({ name: "microphone" });
debug(audioP.state); // granted, denied, prompt
audioP.onchange = () => debug("Changed to", this.state);
```

## Using Stream

#### Play Video of MediaStream

```jsx
const vRef = useRef(null);

if (camStream) vRef.current.srcObject = camStream;

return (<video
          className="h-full scale-medium"
          muted
          autoPlay
          playsInline
          data-setup="{}"
          ref={vRef}
          />)
```

#### Record

```javascript
let audioStream;
let numRecordedChunks = 0;
let recordedChunks = [];
let recorder;

const recorderOnDataAvailable = event => {
  console.log("Data available");
  if (event.data && event.data.size > 0) {
    recordedChunks.push(event.data);
    numRecordedChunks += event.data.byteLength;
  }
};


const getMediaStream = stream => {
  stream.onended = () => {
    console.log("Media stream ended.");
  };

  if (audioStream !== null) {
    console.log("Adding audio track.");
    let audioTracks = audioStream.getAudioTracks();
    stream.addTrack(audioTracks[0]);
  }

  try {
    console.log("Start recording the stream.");
    recorder = new MediaRecorder(stream, { mimeType: "video/webm" });
  } catch (e) {
    console.assert(false, "Exception while creating MediaRecorder: " + e);
    return;
  }

  recorder.ondataavailable = recorderOnDataAvailable;
  recorder.onstop = () => {
    console.log("recorderOnStop fired");
  };
  recorder.start();
  console.log("Recorder is started.");
};
```

Actually then using that recording

```jsx
const play = () => {
  const blob = new Blob(recordedChunks, { type: recordedChunks[0].type });
  const blobURL = URL.createObjectURL(blob);
  let currentRecording = (blobURL);
  console.log(recordedChunks, blob, blobURL);
};

return (
  <video 
      controls autoPlay 
      data-setup="{}" src={currentRecording} 
    />);
```

This sends it to transloadit, but you can also use the base uppy to send straight to S3

```javascript
import Robodog from "@uppy/robodog";

function send() {
  const blob = new Blob(recordedChunks, { type: recordedChunks[0].type });

  const resultPromise = Robodog.upload([blob], {
    params: {
      auth: { key: "352f4e9e50f84a4591c9f2039571cbc5" },
      template_id: "ad391eea34034ef28e04e8ad1a024b14"
    }
  });
  resultPromise
    .then(bundle => {
    console.log("TRANSLOAD it success");
    console.log(bundle.transloadit);
    console.log(bundle.results); 
  })
    .catch(err => console.error("Transerr", err));
}
```

## Advanced

Recording a web video/audio will not have the duration set in the header. To let the file know the duration, you can skip to the end and it will figure it out.

```javascript
  useEffect(() => {
    vRef.current.onloadedmetadata = () => {
      vRef.current.currentTime = 9999999999;
      vRef.current.ontimeupdate = function() {
        vRef.current.ontimeupdate = null;
        vRef.current.currentTime = 0.1;
        vRef.current.currentTime = 0;
        vRef.current.play();
      };
      console.log("LOADS");
      vRef.current.onloadedmetadata = null;
    };
  }, []);
```

### Constraints

If the browser doesn't support then these are ignored, check `navigator.mediaDevices.getSupportedConstraints()`

```javascript
audio: {
  echoCancellation: true,
  autoGainControl: true,
  noiseSuppression: true
}

video: {
  frameRate: 30
}

//prefer camera if available
{ video: { deviceId: myPreferredCameraDeviceId } }
//only this camera
{ video: { deviceId: { exact: myExactCameraOrBustDeviceId } } }
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://openai.gitbook.io/code-cheatsheets/js/webjs/media.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
