diff --git a/extra/youtube/authors.txt b/extra/youtube/authors.txt new file mode 100644 index 0000000000..e091bb8164 --- /dev/null +++ b/extra/youtube/authors.txt @@ -0,0 +1 @@ +John Benediktsson diff --git a/extra/youtube/summary.txt b/extra/youtube/summary.txt new file mode 100644 index 0000000000..f08ee0367e --- /dev/null +++ b/extra/youtube/summary.txt @@ -0,0 +1 @@ +Wrapper for YouTube.com API. diff --git a/extra/youtube/youtube.factor b/extra/youtube/youtube.factor new file mode 100644 index 0000000000..900f01e2e6 --- /dev/null +++ b/extra/youtube/youtube.factor @@ -0,0 +1,73 @@ +! Copyright (C) 2013 John Benediktsson +! See http://factorcode.org/license.txt for BSD license + +USING: assocs http.client kernel make math.order sequences +splitting urls urls.encoding ; + +IN: youtube + +TUPLE: encoding extension resolution video-codec profile +video-bitrate audio-codec audio-bitrate ; + +CONSTANT: encodings H{ + + ! Flash Video + { 5 T{ encoding f "flv" "240p" "Sorenson H.263" f "0.25" "MP3" 64 } } + { 6 T{ encoding f "flv" "270p" "Sorenson H.263" f "0.8" "MP3" 64 } } + { 34 T{ encoding f "flv" "360p" "H.264" "Main" "0.5" "AAC" 128 } } + { 35 T{ encoding f "flv" "480p" "H.264" "Main" "0.8-1" "AAC" 128 } } + + ! 3GP + { 36 T{ encoding f "3gp" "240p" "MPEG-4 Visual" "Simple" "0.17" "AAC" 38 } } + { 13 T{ encoding f "3gp" f "MPEG-4 Visual" f "0.5" "AAC" f } } + { 17 T{ encoding f "3gp" "144p" "MPEG-4 Visual" "Simple" "0.05" "AAC" 24 } } + + ! MPEG-4 + { 18 T{ encoding f "mp4" "360p" "H.264" "Baseline" "0.5" "AAC" 96 } } + { 22 T{ encoding f "mp4" "720p" "H.264" "High" "2-2.9" "AAC" 192 } } + { 37 T{ encoding f "mp4" "1080p" "H.264" "High" "3-4.3" "AAC" 192 } } + { 38 T{ encoding f "mp4" "3072p" "H.264" "High" "3.5-5" "AAC" 192 } } + { 82 T{ encoding f "mp4" "360p" "H.264" "3D" "0.5" "AAC" 96 } } + { 83 T{ encoding f "mp4" "240p" "H.264" "3D" "0.5" "AAC" 96 } } + { 84 T{ encoding f "mp4" "720p" "H.264" "3D" "2-2.9" "AAC" 152 } } + { 85 T{ encoding f "mp4" "520p" "H.264" "3D" "2-2.9" "AAC" 152 } } + + ! WebM + { 43 T{ encoding f "webm" "360p" "VP8" f "0.5" "Vorbis" 128 } } + { 44 T{ encoding f "webm" "480p" "VP8" f "1" "Vorbis" 128 } } + { 45 T{ encoding f "webm" "720p" "VP8" f "2" "Vorbis" 192 } } + { 46 T{ encoding f "webm" "1080p" "VP8" f f "Vorbis" 192 } } + { 100 T{ encoding f "webm" "360p" "VP8" "3D" f "Vorbis" 128 } } + { 101 T{ encoding f "webm" "360p" "VP8" "3D" f "Vorbis" 192 } } + { 102 T{ encoding f "webm" "720p" "VP8" "3D" f "Vorbis" 192 } } +} + +CONSTANT: video-info-url URL" http://www.youtube.com/get_video_info" + +: get-video-info ( video-id -- video-info ) + video-info-url clone + 3 "asv" set-query-param + "detailpage" "el" set-query-param + "en_US" "hl" set-query-param + swap "video_id" set-query-param + http-get* query>assoc ; + +: video-formats ( video-info -- video-formats ) + "url_encoded_fmt_stream_map" of "," split + [ query>assoc ] map ; + +: video-download-url ( video-format -- url ) + [ "url" of ] [ "sig" of ] bi "&signature=" glue ; + +: sanitize ( title -- title' ) + [ 0 31 between? not ] filter + [ "\"#$%'*,./:;<>?^|~\\" member? not ] filter + 200 short head ; + +: download-video ( video-id -- ) + get-video-info [ + video-formats [ "type" of "video/mp4" head? ] find nip + video-download-url + ] [ + "title" of sanitize ".mp4" append download-to + ] bi ;