diff --git a/docs/supportedsites.md b/docs/supportedsites.md
index 170e8483..2b98722f 100644
--- a/docs/supportedsites.md
+++ b/docs/supportedsites.md
@@ -1018,7 +1018,7 @@ Consider all listed sites to potentially be NSFW.
| VSCO |
https://vsco.co/ |
- Avatars, Collections, Galleries, individual Images, Spaces, User Profiles |
+ Avatars, Collections, Galleries, individual Images, Spaces, User Profiles, Videos |
|
diff --git a/gallery_dl/extractor/vsco.py b/gallery_dl/extractor/vsco.py
index 1c0c1720..b3ce99db 100644
--- a/gallery_dl/extractor/vsco.py
+++ b/gallery_dl/extractor/vsco.py
@@ -38,7 +38,9 @@ class VscoExtractor(Extractor):
if img["is_video"]:
if not videos:
continue
- url = "https://" + img["video_url"]
+ url = img["video_url"]
+ if not url.startswith("ytdl:"):
+ url = "https://" + url
else:
base = img["responsive_url"].partition("/")[2]
cdn, _, path = base.partition("/")
@@ -63,6 +65,9 @@ class VscoExtractor(Extractor):
"height": img["height"],
"description": img.get("description") or "",
})
+ if data["extension"] == "m3u8":
+ data["_ytdl_manifest"] = "hls"
+ data["extension"] = "mp4"
yield Message.Url, url, data
def images(self):
@@ -294,12 +299,33 @@ class VscoImageExtractor(VscoExtractor):
pattern = USER_PATTERN + r"/media/([0-9a-fA-F]+)"
example = "https://vsco.co/USER/media/0123456789abcdef"
- def __init__(self, match):
- VscoExtractor.__init__(self, match)
- self.media_id = match.group(2)
-
def images(self):
- url = "{}/{}/media/{}".format(self.root, self.user, self.media_id)
+ url = "{}/{}/media/{}".format(self.root, self.user, self.groups[1])
data = self._extract_preload_state(url)
media = data["medias"]["byId"].popitem()[1]["media"]
return (self._transform_media(media),)
+
+
+class VscoVideoExtractor(VscoExtractor):
+ """Extractor for vsco.co videos links"""
+ subcategory = "video"
+ pattern = USER_PATTERN + r"/video/([^/?#]+)"
+ example = "https://vsco.co/USER/video/012345678-9abc-def0"
+
+ def images(self):
+ url = "{}/{}/video/{}".format(self.root, self.user, self.groups[1])
+ data = self._extract_preload_state(url)
+ media = data["medias"]["byId"].popitem()[1]["media"]
+
+ return ({
+ "_id" : media["id"],
+ "is_video" : True,
+ "grid_name" : "",
+ "upload_date" : media["createdDate"],
+ "responsive_url": media["posterUrl"],
+ "video_url" : "ytdl:" + media.get("playbackUrl"),
+ "image_meta" : None,
+ "width" : media["width"],
+ "height" : media["height"],
+ "description" : media["description"],
+ },)
diff --git a/test/results/vsco.py b/test/results/vsco.py
index 6ea89ac6..60f82918 100644
--- a/test/results/vsco.py
+++ b/test/results/vsco.py
@@ -108,4 +108,24 @@ __tests__ = (
"video": True,
},
+{
+ "#url" : "https://vsco.co/shavonec/video/c5eb34bb-dd13-4d7a-a09c-2a7cd719c9fa",
+ "#category": ("", "vsco", "video"),
+ "#class" : vsco.VscoVideoExtractor,
+ "#pattern" : r"ytdl:https://stream\.mux\.com/3o01XbjqTI4rkeRwPzR17H9i7VSFdWX1h\.m3u8\?token=ey.+",
+
+ "date" : "dt:2020-02-04 15:11:52",
+ "description": "Big news: 🎥 YOU CAN NOW POST VIDEOS TO VSCO ⚡️⚡️💪🏾. \n\n🔗BTS from my #FashionIsActivism panel with the California African American Arts museum ✊🏾",
+ "extension" : "mp4",
+ "filename" : "3o01XbjqTI4rkeRwPzR17H9i7VSFdWX1h",
+ "grid" : "",
+ "id" : "c5eb34bb-dd13-4d7a-a09c-2a7cd719c9fa",
+ "meta" : {},
+ "tags" : [],
+ "user" : "shavonec",
+ "video" : True,
+ "width" : 624,
+ "height" : 1232,
+},
+
)