Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Highlighter] - Additional tracking #5310

Merged
merged 11 commits into from
Mar 1, 2025
16 changes: 13 additions & 3 deletions app/components-react/highlighter/ExportModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ function ExportModal({ close, streamId }: { close: () => void; streamId: string
/>
);
}
return <PlatformSelect onClose={close} videoName={videoName} />;
return <PlatformSelect onClose={close} videoName={videoName} streamId={streamId} />;
}

function ExportProgress() {
Expand Down Expand Up @@ -301,7 +301,15 @@ function ExportOptions({
);
}

function PlatformSelect({ onClose, videoName }: { onClose: () => void; videoName: string }) {
function PlatformSelect({
onClose,
videoName,
streamId,
}: {
onClose: () => void;
videoName: string;
streamId: string | undefined;
}) {
const { store, clearUpload, getStreamTitle } = useController(ExportModalCtx);
const { UserService } = Services;
const { isYoutubeLinked } = useVuex(() => ({
Expand Down Expand Up @@ -332,7 +340,9 @@ function PlatformSelect({ onClose, videoName }: { onClose: () => void; videoName
nowrap
options={platformOptions}
/>
{platform === 'youtube' && <YoutubeUpload defaultTitle={videoName} close={onClose} />}
{platform === 'youtube' && (
<YoutubeUpload defaultTitle={videoName} close={onClose} streamId={streamId} />
)}
{platform !== 'youtube' && <StorageUpload onClose={onClose} platform={platform} />}
</Form>
);
Expand Down
9 changes: 8 additions & 1 deletion app/components-react/highlighter/PreviewModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,21 @@ export default function PreviewModal({
close: () => void;
streamId: string | undefined;
}) {
const { HighlighterService } = Services;
const { HighlighterService, UsageStatisticsService } = Services;
const clips = HighlighterService.getClips(HighlighterService.views.clips, streamId);
const { intro, outro } = HighlighterService.views.video;
const audioSettings = HighlighterService.views.audio;
const [currentClipIndex, setCurrentClipIndex] = useState(0);
const currentClipIndexRef = useRef(0);
const sortedClips = [...sortClipsByOrder(clips, streamId).filter(c => c.enabled)];

useEffect(() => {
UsageStatisticsService.recordAnalyticsEvent('AIHighlighter', {
type: 'PreviewViewed',
streamId,
});
}, []);

const playlist = [
...(intro.duration
? [
Expand Down
2 changes: 1 addition & 1 deletion app/components-react/highlighter/SettingsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ export default function SettingsView({
style={{ width: 'fit-content' }}
type="primary"
onClick={() => {
HighlighterService.actions.installAiHighlighter(true);
HighlighterService.actions.installAiHighlighter(true, 'Highlighter-tab');
}}
>
{$t('Install AI Highlighter App')}
Expand Down
20 changes: 14 additions & 6 deletions app/components-react/highlighter/YoutubeUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ import * as remote from '@electron/remote';
import VideoPreview from './VideoPreview';
import UploadProgress from './UploadProgress';

export default function YoutubeUpload(props: { defaultTitle: string; close: () => void }) {
export default function YoutubeUpload(props: {
defaultTitle: string;
close: () => void;
streamId: string | undefined;
}) {
const [title, setTitle] = useState(props.defaultTitle);
const streamId = props.streamId;
const [description, setDescription] = useState('');
const [privacy, setPrivacy] = useState('private');
const [urlCopied, setUrlCopied] = useState(false);
Expand Down Expand Up @@ -107,11 +112,14 @@ export default function YoutubeUpload(props: { defaultTitle: string; close: () =
type="primary"
onClick={() => {
UsageStatisticsService.actions.recordFeatureUsage('HighlighterUpload');
HighlighterService.actions.uploadYoutube({
title,
description,
privacyStatus: privacy as TPrivacyStatus,
});
HighlighterService.actions.uploadYoutube(
{
title,
description,
privacyStatus: privacy as TPrivacyStatus,
},
streamId,
);
}}
>
{$t('Publish')}
Expand Down
10 changes: 9 additions & 1 deletion app/components-react/pages/Highlighter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import UpdateModal from 'components-react/highlighter/UpdateModal';
import { EAvailableFeatures } from 'services/incremental-rollout';

export default function Highlighter(props: { params?: { view: string } }) {
const { HighlighterService, IncrementalRolloutService } = Services;
const { HighlighterService, IncrementalRolloutService, UsageStatisticsService } = Services;
const aiHighlighterFeatureEnabled = IncrementalRolloutService.views.featureIsEnabled(
EAvailableFeatures.aiHighlighter,
);
Expand Down Expand Up @@ -50,6 +50,14 @@ export default function Highlighter(props: { params?: { view: string } }) {
}, []);

const [viewState, setViewState] = useState<IViewState>(initialViewState);

useEffect(() => {
UsageStatisticsService.recordAnalyticsEvent('Highlighter', {
type: 'HighlighterTabViewed',
view: viewState,
});
}, [viewState]);

const updaterModal = (
<UpdateModal
version={v.highlighterVersion}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export default function AiHighlighterToggle({
size="small"
type="primary"
onClick={() => {
HighlighterService.installAiHighlighter();
HighlighterService.installAiHighlighter(false, 'Go-live-flow');
}}
>
Install AI Highlighter
Expand Down
15 changes: 13 additions & 2 deletions app/services/highlighter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,7 @@ export class HighlighterService extends PersistentStatefulService<IHighlighterSt
transitionDuration: this.views.transitionDuration,
transition: this.views.transition,
useAiHighlighter: this.views.useAiHighlighter,
streamId,
},
handleFrame,
setExportInfo,
Expand Down Expand Up @@ -1110,7 +1111,15 @@ export class HighlighterService extends PersistentStatefulService<IHighlighterSt
}
}

async installAiHighlighter(downloadNow: boolean = false) {
async installAiHighlighter(
downloadNow: boolean = false,
location: 'Highlighter-tab' | 'Go-live-flow',
) {
this.usageStatisticsService.recordAnalyticsEvent('AIHighlighter', {
type: 'Installation',
location,
});

this.setAiHighlighter(true);
if (downloadNow) {
await this.aiHighlighterUpdater.isNewVersionAvailable();
Expand Down Expand Up @@ -1248,6 +1257,7 @@ export class HighlighterService extends PersistentStatefulService<IHighlighterSt
type: 'Detection',
clips: highlighterResponse.length,
game: 'Fortnite', // hardcode for now
streamId: this.streamMilestones?.streamId,
});
console.log('✅ Final HighlighterData', highlighterResponse);
} catch (error: unknown) {
Expand Down Expand Up @@ -1343,7 +1353,7 @@ export class HighlighterService extends PersistentStatefulService<IHighlighterSt
this.CLEAR_UPLOAD();
}

async uploadYoutube(options: IYoutubeVideoUploadOptions) {
async uploadYoutube(options: IYoutubeVideoUploadOptions, streamId: string | undefined) {
if (!this.userService.state.auth?.platforms.youtube) {
throw new Error('Cannot upload without YT linked');
}
Expand Down Expand Up @@ -1407,6 +1417,7 @@ export class HighlighterService extends PersistentStatefulService<IHighlighterSt
this.views.useAiHighlighter ? 'AIHighlighter' : 'Highlighter',
{
type: 'UploadYouTubeSuccess',
streamId,
privacy: options.privacyStatus,
videoLink:
options.privacyStatus === 'public'
Expand Down
3 changes: 3 additions & 0 deletions app/services/highlighter/rendering/start-rendering.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface IRenderingConfig {
transitionDuration: number;
transition: ITransitionInfo;
useAiHighlighter: boolean;
streamId: string | undefined;
}
export async function startRendering(
renderingConfig: IRenderingConfig,
Expand All @@ -43,6 +44,7 @@ export async function startRendering(
const transitionDuration = renderingConfig.transitionDuration;
const transition = renderingConfig.transition;
const useAiHighlighter = renderingConfig.useAiHighlighter;
const streamId = renderingConfig.streamId;

let fader: AudioCrossfader | null = null;
let mixer: AudioMixer | null = null;
Expand Down Expand Up @@ -200,6 +202,7 @@ export async function startRendering(
preset: exportInfo.preset,
duration: totalFramesAfterTransitions / exportOptions.fps,
isPreview,
streamId,
});
break;
}
Expand Down
Loading