( url: string, )
| 260 | } |
| 261 | |
| 262 | export async function downloadLoomVideo( |
| 263 | url: string, |
| 264 | ): Promise<LoomDownloadResult> { |
| 265 | if (!url || typeof url !== "string") { |
| 266 | return { success: false, error: "Please provide a valid URL." }; |
| 267 | } |
| 268 | |
| 269 | const videoId = extractLoomVideoId(url.trim()); |
| 270 | |
| 271 | if (!videoId) { |
| 272 | return { |
| 273 | success: false, |
| 274 | error: |
| 275 | "Invalid Loom URL. Please paste a valid Loom video link (e.g. https://www.loom.com/share/abc123).", |
| 276 | }; |
| 277 | } |
| 278 | |
| 279 | try { |
| 280 | const downloadUrl = await getLoomDownloadUrl(videoId); |
| 281 | |
| 282 | if (!downloadUrl) { |
| 283 | return { |
| 284 | success: false, |
| 285 | error: |
| 286 | "Could not retrieve a download URL. The video may be private, password-protected, or the link may have expired.", |
| 287 | }; |
| 288 | } |
| 289 | |
| 290 | const [videoName, oembedMeta] = await Promise.all([ |
| 291 | fetchVideoName(videoId), |
| 292 | fetchLoomOEmbed(videoId), |
| 293 | ]); |
| 294 | return { |
| 295 | success: true, |
| 296 | videoId, |
| 297 | videoName: videoName ?? undefined, |
| 298 | downloadUrl, |
| 299 | downloadMode: isDirectMp4Url(downloadUrl) |
| 300 | ? "direct-download" |
| 301 | : "browser-conversion", |
| 302 | durationSeconds: oembedMeta?.duration, |
| 303 | width: oembedMeta?.width, |
| 304 | height: oembedMeta?.height, |
| 305 | requiresProxy: false, |
| 306 | }; |
| 307 | } catch { |
| 308 | return { |
| 309 | success: false, |
| 310 | error: |
| 311 | "An unexpected error occurred. Please try again or check your internet connection.", |
| 312 | }; |
| 313 | } |
| 314 | } |
| 315 | |
| 316 | async function importLoomVideoForOwner({ |
| 317 | loomUrl, |
no test coverage detected