Skip to content

Commit

Permalink
[Highlighter] - Additional tracking (#5310)
Browse files Browse the repository at this point in the history
* additional tracking

* forgot property

* switched tracking to record shown

* removed unused logs

* Revert "removed unused logs"

This reverts commit 661ef41.

* added error tracking

* track update error

* fix tracking property casing

---------

Co-authored-by: jankalthoefer <[email protected]>
  • Loading branch information
marvinoffers and jankalthoefer authored Mar 1, 2025
1 parent 01f3c25 commit e2ff3f4
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 17 deletions.
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
6 changes: 5 additions & 1 deletion app/components-react/highlighter/PreviewModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default function PreviewModal({
streamId: string | undefined;
emitSetShowModal: (modal: TModalClipsView | null) => void;
}) {
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;
Expand All @@ -41,6 +41,10 @@ export default function PreviewModal({
const currentClipIndexRef = useRef(initialIndex);
const [showDisabled, setShowDisabled] = useState(true);

useEffect(() => {
UsageStatisticsService.recordShown('ClipsPreview', streamId);
}, []);

function getInitialIndex(introDuration: number | null, sortedClips: TClip[]): number {
if (introDuration) return 0;
const firstEnabledIndex = sortedClips.findIndex(clip => clip.enabled);
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
7 changes: 6 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,11 @@ export default function Highlighter(props: { params?: { view: string } }) {
}, []);

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

useEffect(() => {
UsageStatisticsService.recordShown('HighlighterTab', viewState.view);
}, [viewState]);

const updaterModal = (
<UpdateModal
version={v.highlighterVersion}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export default function AiHighlighterToggle({
size="small"
type="primary"
onClick={() => {
HighlighterService.installAiHighlighter();
HighlighterService.installAiHighlighter(false, 'Go-live-flow');
}}
>
Install AI Highlighter
Expand Down
4 changes: 2 additions & 2 deletions app/services/highlighter/ai-highlighter-updater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export class AiHighlighterUpdater {
*/
public async isNewVersionAvailable(): Promise<boolean> {
// check if updater checked version in current session already
if (this.versionChecked) {
if (this.versionChecked || Utils.getHighlighterEnvironment() === 'local') {
return false;
}

Expand Down Expand Up @@ -235,7 +235,7 @@ export class AiHighlighterUpdater {
const binPath = path.resolve(AiHighlighterUpdater.basepath, 'bin');
const outdateVersionPresent = existsSync(binPath);

// backup the ouotdated version in case something goes bad
// backup the outdated version in case something goes bad
if (outdateVersionPresent) {
console.log('backing up outdated version...');
const backupPath = path.resolve(AiHighlighterUpdater.basepath, 'bin.bkp');
Expand Down
31 changes: 29 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 All @@ -1136,6 +1145,12 @@ export class HighlighterService extends PersistentStatefulService<IHighlighterSt
this.SET_UPDATER_STATE(true);
this.SET_HIGHLIGHTER_VERSION(this.aiHighlighterUpdater.version || '');
await this.aiHighlighterUpdater.update(progress => this.updateProgress(progress));
} catch (e: unknown) {
console.error('Error updating AI Highlighter:', e);
this.usageStatisticsService.recordAnalyticsEvent('Highlighter', {
type: 'UpdateError',
newVersion: this.aiHighlighterUpdater.version,
});
} finally {
this.SET_UPDATER_STATE(false);
}
Expand Down Expand Up @@ -1248,14 +1263,25 @@ 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) {
if (error instanceof Error && error.message === 'Highlight generation canceled') {
setStreamInfo.state.type = EAiDetectionState.CANCELED_BY_USER;
this.usageStatisticsService.recordAnalyticsEvent('AIHighlighter', {
type: 'DetectionCanceled',
reason: EAiDetectionState.CANCELED_BY_USER,
game: 'Fortnite',
});
} else {
console.error('Error in highlight generation:', error);
setStreamInfo.state.type = EAiDetectionState.ERROR;
this.usageStatisticsService.recordAnalyticsEvent('AIHighlighter', {
type: 'DetectionFailed',
reason: EAiDetectionState.ERROR,
game: 'Fortnite',
});
}
} finally {
setStreamInfo.abortController = undefined;
Expand Down Expand Up @@ -1343,7 +1369,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 +1433,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

0 comments on commit e2ff3f4

Please sign in to comment.