Skip to content

Commit

Permalink
Merge branch 'main' into pr/44
Browse files Browse the repository at this point in the history
  • Loading branch information
richiemcilroy committed Jul 9, 2024
2 parents d51d01d + 2a8db9c commit 01ab609
Show file tree
Hide file tree
Showing 66 changed files with 7,022 additions and 650 deletions.
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

NEXT_PUBLIC_ENVIRONMENT=development
NEXT_PUBLIC_URL=http://localhost:3000
NEXT_PUBLIC_TASKS_URL=http://localhost:3002

# IMPORTANT FOR LOCAL DEV:
# This determines whether or not the app will run in "local mode".
Expand All @@ -41,6 +42,9 @@ CAP_AWS_SECRET_KEY=
CAP_AWS_BUCKET=
CAP_AWS_REGION=

# -- Deepgram (for transcription) ****************
DEEPGRAM_API_KEY=

# -- resend ****************
## For use with email authentication (sign up, sign in, forgot password)
RESEND_API_KEY=
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</p>
<h1 align="center"><b>Cap</b></h1>
<p align="center">
Effortless, instant screen sharing. Open source and cross-platform.
The open source Loom alternative.
<br />
<a href="https://cap.so"><strong>Cap.so »</strong></a>
<br />
Expand All @@ -24,7 +24,7 @@

> NOTE: Cap is under active development, and is currently in public beta. This repository is updated regularly with changes and new releases.
Cap is an open source alternative to Loom. It's a video messaging tool that allows you to record, edit and share videos in seconds.
Cap is the open source alternative to Loom. It's a video messaging tool that allows you to record, edit and share videos in seconds.

![cap-emoji-banner](https://github.com/CapSoftware/cap/assets/33632126/85425396-ad31-463b-b209-7c4bdf7e2e4f)

Expand Down
4 changes: 4 additions & 0 deletions apps/desktop/src-tauri/src/capture/src/quartz/capturer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ impl Capturer {
stream
};

if queue.is_null() {
return Err(CGError::Failure);
}

match unsafe { CGDisplayStreamStart(stream) } {
CGError::Success => Ok(Capturer {
stream, queue, width, height, format, display
Expand Down
10 changes: 6 additions & 4 deletions apps/desktop/src-tauri/src/upload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ pub async fn upload_file(
"audio/aac"
} else if file_path.to_lowercase().ends_with(".webm") {
"audio/webm"
} else if file_path.to_lowercase().ends_with(".mp3") {
"audio/mpeg"
} else {
"video/mp2t"
};
Expand Down Expand Up @@ -155,14 +157,14 @@ pub fn get_video_duration(file_path: &str) -> Result<f64, std::io::Error> {
.output()?;

let output_str = str::from_utf8(&output.stderr).unwrap();
let duration_regex = Regex::new(r"Duration: (\d{2}):(\d{2}):(\d{2})\.\d{2}").unwrap();
let duration_regex = Regex::new(r"Duration: (\d{2}):(\d{2}):(\d{2})\.(\d{2})").unwrap();
let caps = duration_regex.captures(output_str).unwrap();

let hours: f64 = caps.get(1).unwrap().as_str().parse().unwrap();
let minutes: f64 = caps.get(2).unwrap().as_str().parse().unwrap();
let seconds: f64 = caps.get(3).unwrap().as_str().parse().unwrap();

let duration = hours * 3600.0 + minutes * 60.0 + seconds;
let seconds: f64 = caps.get(3).unwrap().as_str().parse::<f64>().unwrap();
let milliseconds: f64 = caps.get(4).unwrap().as_str().parse::<f64>().unwrap() / 100.0;
let duration = hours * 3600.0 + minutes * 60.0 + seconds + milliseconds;

Ok(duration)
}
Expand Down
7 changes: 7 additions & 0 deletions apps/embed/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
extends: [require.resolve("config/eslint/web.js")],
parserOptions: {
tsconfigRootDir: __dirname,
project: "./tsconfig.json",
},
};
36 changes: 36 additions & 0 deletions apps/embed/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
pnpm-lock.yaml
3 changes: 3 additions & 0 deletions apps/embed/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Cap Embed App

This Next.js app is used for Cap web embeds.
Binary file added apps/embed/app/favicon.ico
Binary file not shown.
26 changes: 26 additions & 0 deletions apps/embed/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

.wrapper {
@apply mx-auto w-[92%] max-w-screen-xl;
}

.wrapper-max {
@apply max-w-screen-2xl;
}

.wrapper-sm {
@apply max-w-5xl;
}

*,
*:before,
*:after {
box-sizing: border-box;
}

* {
min-width: 0;
min-height: 0;
}
57 changes: 57 additions & 0 deletions apps/embed/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import "@/app/globals.css";
import { Toaster } from "react-hot-toast";
import type { Metadata } from "next";

export const metadata: Metadata = {
title:
"Cap — Effortless, instant screen sharing. Open source and cross-platform.",
description:
"Cap is the open source alternative to Loom. Lightweight, powerful, and stunning. Record and share in seconds.",
openGraph: {
title:
"Cap — Effortless, instant screen sharing. Open source and cross-platform.",
description:
"Cap is the open source alternative to Loom. Lightweight, powerful, and stunning. Record and share in seconds.",
type: "website",
url: "https://cap.so",
images: ["https://cap.so/og.png"],
},
};

export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<head>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicon-16x16.png"
/>
<link rel="manifest" href="/site.webmanifest" />
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5" />
<meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#ffffff" />
</head>
<body className="w-screen h-screen">
<Toaster />
<main className="w-full h-full overflow-hidden">{children}</main>
</body>
</html>
);
}
7 changes: 7 additions & 0 deletions apps/embed/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default async function EmbedPage() {
return (
<div>
<p>Embed</p>
</div>
);
}
21 changes: 21 additions & 0 deletions apps/embed/app/view/[videoId]/Share.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"use client";

import { ShareVideo } from "./_components/ShareVideo";
import { comments as commentsSchema, videos } from "@cap/database/schema";
import { userSelectProps } from "@cap/database/auth/session";

export const Share = ({
data,
user,
comments,
}: {
data: typeof videos.$inferSelect;
user: typeof userSelectProps | null;
comments: (typeof commentsSchema.$inferSelect)[];
}) => {
return (
<div className="w-full h-full space-y-6">
<ShareVideo data={data} user={user} comments={comments} />
</div>
);
};
42 changes: 42 additions & 0 deletions apps/embed/app/view/[videoId]/_components/AudioPlayer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { memo, forwardRef, useEffect } from "react";
import Hls from "hls.js";

export const AudioPlayer = memo(
forwardRef<HTMLAudioElement, { src: string; onReady: () => void }>(
({ src, onReady }, ref) => {
useEffect(() => {
const audio = ref as React.MutableRefObject<HTMLAudioElement | null>;

if (!audio.current) return;

let hls: Hls | null = null;

if (Hls.isSupported()) {
hls = new Hls();
hls.loadSource(src);
hls.attachMedia(audio.current);
hls.on(Hls.Events.MANIFEST_PARSED, () => {
onReady();
});
} else if (audio.current.canPlayType("application/vnd.apple.mpegurl")) {
audio.current.src = src;
audio.current.addEventListener(
"loadedmetadata",
() => {
onReady();
},
{ once: true }
);
}

return () => {
if (hls) {
hls.destroy();
}
};
}, [src, onReady, ref]);

return <audio ref={ref} controls={false} style={{ display: "none" }} />;
}
)
);
Loading

0 comments on commit 01ab609

Please sign in to comment.