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

feat: add loom video support #110

Merged
merged 4 commits into from
Feb 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions __tests__/loom.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* eslint max-len: 0 */
import fn from '../src/index.js';

/**
* Loom should be able to find these patterns:
*
* https://www.loom.com/share/*
* https://www.loom.com/share/*?
* https://www.loom.com/embed/*
*/
describe('Loom', () => {
test('extracts loom video id in url without query parameters', () => {
expect(fn('https://www.loom.com/share/1234').id).toBe('1234');
expect(fn('https://loom.com/share/1234').id).toBe('1234');
});

test('extracts loom video ids without www.', () => {
expect(fn('https://loom.com/share/1234').id).toBe('1234');
expect(fn('https://loom.com/embed/1234').id).toBe('1234');
});

test('extracts loom video id in url with query parameters', () => {
expect(fn('https://www.loom.com/share/1234?source=embed&t=20').id).toBe('1234');
expect(fn('https://loom.com/share/1234?source=embed&t=20').id).toBe('1234');
expect(fn('https://www.loom.com/share/1234?source=embed&t=20#foo').id).toBe('1234');
expect(fn('https://loom.com/share/1234?source=embed&t=20#foo').id).toBe('1234');
});

test('extracts video id from loom embed codes', () => {
expect(fn('https://www.loom.com/embed/1234?source=embed&t=20').id).toBe('1234');
expect(fn('https://loom.com/embed/1234?source=embed&t=20').id).toBe('1234');
expect(fn('https://www.loom.com/embed/1234?source=embed&t=20#foo').id).toBe('1234');
expect(fn('https://loom.com/embed/1234?source=embed&t=20#foo').id).toBe('1234');
expect(fn('<div style="position: relative; padding-bottom: 62.5%; height: 0;"><iframe src="https://www.loom.com/embed/12345" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></iframe></div>').id).toBe('12345');
expect(fn('<div style="position: relative; padding-bottom: 62.5%; height: 0;"><iframe src="https://loom.com/embed/12345" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></iframe></div>').id).toBe('12345');
expect(fn('<div style="position: relative; padding-bottom: 62.5%; height: 0;"><iframe src="https://www.loom.com/embed/123456?source=embed&t=20#foo" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></iframe></div>').id).toBe('123456');
expect(fn('<div style="position: relative; padding-bottom: 62.5%; height: 0;"><iframe src="https://loom.com/embed/123456?source=embed&t=20#foo" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></iframe></div>').id).toBe('123456');
});

test('returns undefined for unknown video ids', () => {
const actual = fn('https://www.loom.com');
expect(actual.id).toBeUndefined();
expect(actual.service).toBe('loom');
});
});
2 changes: 1 addition & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ export default function getVideoId(
url: string
): {
id: string | undefined;
service: 'youtube' | 'vimeo' | 'vine' | 'videopress' | 'microsoftstream' | 'tiktok' | 'dailymotion' | undefined;
service: 'youtube' | 'vimeo' | 'vine' | 'videopress' | 'microsoftstream' | 'tiktok' | 'dailymotion' | 'loom' | undefined;
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "get-video-id",
"version": "3.5.3",
"description": "Get the YouTube, Vimeo, Vine, Microsoft Steam, Dailymotion, TikTok or VideoPress video id from a url or embed string.",
"description": "Get the YouTube, Vimeo, Vine, VideoPress, TikTok, Microsoft Stream, Loom or Dailymotion video id from a url or embed string.",
"license": "MIT",
"repository": "radiovisual/get-video-id",
"main": "dist/get-video-id.js",
Expand Down Expand Up @@ -43,6 +43,7 @@
"url",
"vine",
"vimeo",
"loom",
"youtube",
"videopress",
"microsoft stream",
Expand Down
30 changes: 26 additions & 4 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
# get-video-id [![codecov](https://codecov.io/gh/radiovisual/get-video-id/branch/master/graph/badge.svg?token=fG7V2VRDYY)](https://codecov.io/gh/radiovisual/get-video-id)

> Get the YouTube, Vimeo, Vine, VideoPress, TikTok, Microsoft Stream and Dailymotion video id from a url or embed string.
> Get the YouTube, Vimeo, Vine, VideoPress, TikTok, Microsoft Stream, Loom or Dailymotion video id from a url or embed string.

**Pull Requests are welcome** if you would like to see support for other video services or if you find an unsupported video url pattern.

## Install

You can install with npm:

```
$ npm install --save get-video-id
```

or with yarn:

```
$ yarn add get-video-id
```

## Import

Expand Down Expand Up @@ -70,8 +77,8 @@ Returns a metadata `Object` with the video `id` and `service` name:

```
{
id: 'String',
service: 'String'
id: `String` | `undefined`,
service: `String` | `undefined`
}
```

Expand All @@ -98,7 +105,7 @@ http://y2u.be/*
youtube://
```

*YouTube Shorts**
**YouTube Shorts**
```
https://youtube.com/shorts/*
https://www.youtube.com/shorts/*
Expand Down Expand Up @@ -252,6 +259,7 @@ https://web.microsoftstream.com/embed/video/*
```
<iframe src="https://web.microsoftstream.com/embed/video/*?&" width="640" height="360"></iframe>
```

### TikTok

**TikTok urls**
Expand Down Expand Up @@ -281,6 +289,20 @@ http://dai.ly/*
**:warning: Unsupported Dailymotion urls**
* Channel id urls: `http://www.dailymotion.com/hub/*_title`

### Loom

**Loom urls**
```
https://www.loom.com/share/*
https://www.loom.com/share/*?
https://www.loom.com/embed/*
```

**Loom iframes**
```
<iframe src="https://www.loom.com/embed/*" width="600" height="600"></iframe>
```

## Contributing

If you discover a url pattern that is not covered by this module, please [open an issue](https://github.com/radiovisual/get-video-id/issues) to report it, or [submit a Pull Request](https://github.com/radiovisual/get-video-id/pull/new/master). For any submitted pull requests, please ensure that you include unit test(s) to fully cover your code contribution(s).
Expand Down
6 changes: 6 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import videopress from './videopress.js';
import microsoftStream from './microsoftstream.js';
import tiktok from './tiktok.js';
import dailymotion from './dailymotion.js';
import loom from './loom.js';
import sanitizeUrl from './utils/sanitize-url.js';
import extractGoogleRedirectionUrl from './utils/extract-google-redirection-url.js';

Expand Down Expand Up @@ -61,6 +62,11 @@ function getVideoId(urlString) {
id: dailymotion(url),
service: 'dailymotion',
};
} else if (/loom\.com/.test(url)) {
metadata = {
id: loom(url),
service: 'loom',
};
}

return metadata;
Expand Down
15 changes: 15 additions & 0 deletions src/loom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* Get the loom id.
* @param {string} urlString - the url from which you want to extract the id
* @returns {string|undefined}
*/
export default function loom(urlString) {
const regex = /^https?:\/\/(?:www\.)?loom\.com\/(?:share|embed)\/([\da-zA-Z]+)\/?/;
const matches = regex.exec(urlString);

if (matches && matches.length > 1) {
return matches[1];
}

return undefined;
}
Loading