Skip to content

Commit

Permalink
refactor: desktop capture
Browse files Browse the repository at this point in the history
  • Loading branch information
maltoze committed Aug 31, 2023
1 parent ca0ef2c commit df36dd5
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 170 deletions.
52 changes: 24 additions & 28 deletions src/entries/background/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as Sentry from '@sentry/browser'
import { offscreenUrl, tabCaptureModes } from '~/constants'
import { offscreenUrl } from '~/constants'
import { getCurrentTab, getStreamId, hasOffscreenDocument } from '~/lib/utils'
import { RecordingMode, RecordingOptions } from '~/types'
import { useStore } from '../store'
Expand All @@ -13,6 +13,7 @@ if (process.env.NODE_ENV === 'production') {
let isRecording = false
let recordingMode: RecordingMode | null
let recordingTabId: number | null = null
let resultTabId: number | null = null
const enabledTabs = new Set()

function stopRecording() {
Expand All @@ -22,11 +23,10 @@ function stopRecording() {
})
recordingTabId &&
chrome.tabs.sendMessage(recordingTabId, { type: 'stop-recording' })
useStore.setState({ isRecording: false })
isRecording = false
recordingTabId = null
recordingMode = null
chrome.action.setBadgeText({ text: '' })
if (recordingMode === 'desktop') {
resultTabId &&
chrome.tabs.sendMessage(resultTabId, { type: 'stop-recording' })
}
}

chrome.tabs.onUpdated.addListener((tabId, changeInfo, _tab) => {
Expand Down Expand Up @@ -83,28 +83,17 @@ async function startRecording(data: Partial<RecordingOptions>) {
target: 'offscreen',
data: { streamId, ...data },
})
recordingTabId = tab.id
} else {
chrome.desktopCapture.chooseDesktopMedia(
['screen', 'window', 'audio', 'tab'],
tab,
(streamId, { canRequestAudioTrack }) => {
tab.id &&
chrome.tabs.sendMessage(tab.id, {
type: 'start-recording',
data: {
streamId,
recordingMode: 'desktop',
audio: canRequestAudioTrack,
},
})
}
)
const recordingTab = await chrome.tabs.create({
url: `/src/entries/tabs/main.html?tabId=${tab.id}`,
})
resultTabId = recordingTab.id ?? null
}
chrome.action.setBadgeText({ text: 'REC' })
chrome.action.setBadgeTextColor({ color: '#ffffff' })
chrome.action.setBadgeBackgroundColor({ color: '#dc2626' })
isRecording = true
recordingTabId = tab.id
}

chrome.runtime.onMessage.addListener(
Expand All @@ -114,13 +103,20 @@ chrome.runtime.onMessage.addListener(
}
switch (message.type) {
case 'recording-complete':
isRecording = false
if (recordingMode === 'desktop') {
resultTabId && chrome.tabs.update(resultTabId, { active: true })
} else {
chrome.tabs.create({
url: `/src/entries/tabs/main.html?videoUrl=${encodeURIComponent(
message.videoUrl
)}`,
})
}
chrome.action.setBadgeText({ text: '' })
chrome.tabs.create({
url: `/src/entries/tabs/main.html?videoUrl=${encodeURIComponent(
message.videoUrl
)}`,
})
useStore.setState({ isRecording: false })
isRecording = false
recordingTabId = null
recordingMode = null
break
case 'start-recording':
startRecording(message.data)
Expand Down
8 changes: 5 additions & 3 deletions src/entries/background/offscreen.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { start, stop } from '~/lib/recording'
import Recorder from '~/lib/recording'

const recorder = new Recorder()

chrome.runtime.onMessage.addListener(async (message) => {
if (message.target === 'offscreen') {
switch (message.type) {
case 'start-recording':
start(message.data)
recorder.start(message.data)
break
case 'stop-recording':
stop()
recorder.stop()
break
default:
throw new Error('Unrecognized message:', message.type)
Expand Down
9 changes: 0 additions & 9 deletions src/entries/contentScript/primary/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { useCallback, useEffect, useState } from 'react'
import { tabCaptureModes } from '~/constants'
import { start, stop } from '~/lib/recording'
import { ChromeRuntimeMessage, RecordingOptions } from '~/types'
import { setIsRecording, useStore } from '../../store'
import Controlbar from './components/Controlbar'
Expand Down Expand Up @@ -49,15 +47,8 @@ function App({ appRoot }: AppProps) {
case 'show-controlbar':
setShowControlbar(true)
break
case 'start-recording':
setIsRecording(true)
!tabCaptureModes.includes(recordingMode) &&
message.data &&
start(message.data, () => setIsRecording(false))
break
case 'stop-recording':
setIsRecording(false)
!tabCaptureModes.includes(recordingMode) && stop()
break
default:
break
Expand Down
40 changes: 35 additions & 5 deletions src/entries/tabs/App.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,45 @@
import { useRef } from 'react'
import { useEffect, useRef, useState } from 'react'
import Confetti from 'react-confetti'
import Recorder from '~/lib/recording'
import { RecordingOptions } from '~/types'

const params = new URLSearchParams(location.search)
const videoUrl = params.get('videoUrl')
const tabId = params.get('tabId')

const recorder = new Recorder()

chrome.runtime.onMessage.addListener((message) => {
if (message.type === 'stop-recording') {
recorder.stop()
}
})

export default function App() {
const videoRef = useRef<HTMLVideoElement>(null)
const [videoUrl, setVideoUrl] = useState<string>(params.get('videoUrl') || '')

if (!videoUrl) {
return null
}
useEffect(() => {
if (!tabId) return
const desktopMediaRequestId = chrome.desktopCapture.chooseDesktopMedia(
['screen', 'window', 'audio'],
(streamId, { canRequestAudioTrack }) => {
recorder.start(
{
streamId,
audio: canRequestAudioTrack,
recordingMode: 'desktop',
} as RecordingOptions,
(url) => setVideoUrl(url)
)
tabId && chrome.tabs.update(parseInt(tabId), { active: true })
}
)
return () => {
chrome.desktopCapture.cancelChooseDesktopMedia(desktopMediaRequestId)
}
}, [])

if (!videoUrl) return null

return (
<>
Expand Down
Loading

0 comments on commit df36dd5

Please sign in to comment.