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

Fix wistia downloading issue #51

Merged
merged 5 commits into from
Nov 4, 2023
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
5 changes: 4 additions & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ COURSE_LINK=""
COURSE_DATA_FILE=""

CLIENT_DATE=""
COOKIE_DATA=""
COOKIE_DATA=""

# Quality Available: "Original File", "1080p", "720p", "540p", "360p", "224p"
VIDEO_DOWNLOAD_QUALITY="720p"
44 changes: 31 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,22 @@
# Thinki-Downloader
A php based utility to download courses from Thinkific based sites like PacktPub for personal offline use.

It's been 2+ years of maintaining this repo and meeting new friends through online calls. Initially this project was barebone with just downloading the Html Content and Lesson Videos. With time, many features added was indeed, a requirement of people who pinged through emails and LinkedIn.
<!-- It's been 2+ years of maintaining this repo and meeting new friends through online calls. Initially this project was barebone with just downloading the Html Content and Lesson Videos. With time, many features added was indeed, a requirement of people who pinged through emails and LinkedIn.

~~I am thinking for a online version of it. But I am not sure if it will be a paid service or a free one. Please let me know your thoughts on this :)
Please drop them at [email protected]~~

Update : Thanks to everyone who mailed and messaged on Twitter. I have decided not to go with online version of this script. It might not be a good idea to store your credentials on a server or keep copyright contents on server even if for a limited time. I will try to make this script more user friendly instead. I am currently looking at [NativePHP](https://github.com/NativePHP) and check it out if it helps for multi-platform binary.
Update : Thanks to everyone who mailed and messaged on Twitter. I have decided not to go with online version of this script. It might not be a good idea to store your credentials on a server or keep copyright contents on server even if for a limited time. I will try to make this script more user friendly instead. I am currently looking at [NativePHP](https://github.com/NativePHP) and check it out if it helps for multi-platform binary. -->

If you like this work, consider [buying me some coffee](https://ko-fi.com/sumeet) for motivation!
If you want to support the project, consider [buying me some coffee](https://ko-fi.com/sumeet) for motivation!

## ***Revision 6.2 ~ 3rd March 2023***
## ***Revision 6.3 ~ 4th November 2023***

!NEW! [Thinki-Parser v0.0.1 Experimental Support Added](https://sumeetweb.github.io/Thinki-Parser/)
!FIX! Wistia Video Download Fixed!
!HOT! Quality Selection for Video Downloads!
!HOT! Presentation Downloads with FFMPEG support to merge audio and video files!
!HOT! Beautified file names for video downloads!
!NEW! Download Quiz with Answers (MCQs).
!NEW! Download Shared Files.
!NEW! Resume interrupted downloads anytime.
!NEW! Chapterwise Downloading added!

!NEW! FFMPEG Support in Docker Image!

## Steps:
1. Clone this repo or download the zip file.
Expand All @@ -34,8 +31,22 @@ If you like this work, consider [buying me some coffee](https://ko-fi.com/sumeet
> > For Docker Method, create or modify existing .env file in the root directory of the project and add the following lines:
```bash
COURSE_LINK=""

# If using selective download, add the following line and add the path of course data file downloaded from Thinki-Parser
COURSE_DATA_FILE=""

# Watch YouTube video to know how to get the client date and cookie data
CLIENT_DATE=""
COOKIE_DATA=""

# Set the video download quality. Default is 720p.
# Available Options: "Original File", "1080p", "720p", "540p", "360p", "224p"
VIDEO_DOWNLOAD_QUALITY="720p"
```

If you want to merge audio and video files of presentations, install ffmpeg and set the following flag to true in config.php file, modify the following lines:
```php
$FFMPEG_PRESENTATION_MERGE_FLAG = true;
```

> > Follow the video to set cookie data and client date in the .env file.
Expand All @@ -45,16 +56,23 @@ COOKIE_DATA=""
```php
$clientdate = "PASTE CLIENT DATE HERE";
$cookiedata = "PASTE COOKIE DATA HERE";
```
> > Video is quite old now, but the process is still the same. Will update the video soon.
// Set the video download quality. Default is 720p.
// Available Options: "Original File", "1080p", "720p", "540p", "360p", "224p"
$video_download_quality = "720p";

// Set the following flag to true if you want to merge audio and video files of presentations
$FFMPEG_PRESENTATION_MERGE_FLAG = true;
```

> > Video is quite old now, but the process is still the same. Will update the video tomorrow?
> > [![How to use Thinkifi-Downloader|width=100px](https://img.youtube.com/vi/RqaJkuTz_5g/0.jpg)](https://www.youtube.com/watch?v=RqaJkuTz_5g)
> > https://www.youtube.com/watch?v=RqaJkuTz_5g
> > Note : In the video, the course URL ends with php because I was trying to download a PHP Programming Course for the demo and "php" is the course name slug here ^^

> * $COURSE_LINK FORMAT : `https://URL-OF-WEBSITE/api/course_player/v2/courses/COURSE-NAME-SLUG`

5. Run the following command in the root directory of the project:
> If using docker, run (without ffmpeg):
> If using docker, run:
```bash
docker-compose up
```
Expand Down
1 change: 1 addition & 0 deletions compose.selective.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ services:
- COURSE_DATA_FILE=${COURSE_DATA_FILE}
- CLIENT_DATE=${CLIENT_DATE}
- COOKIE_DATA=${COOKIE_DATA}
- VIDEO_DOWNLOAD_QUALITY=${VIDEO_DOWNLOAD_QUALITY}
1 change: 1 addition & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ services:
- COURSE_LINK=${COURSE_LINK}
- CLIENT_DATE=${CLIENT_DATE}
- COOKIE_DATA=${COOKIE_DATA}
- VIDEO_DOWNLOAD_QUALITY=${VIDEO_DOWNLOAD_QUALITY}
4 changes: 3 additions & 1 deletion config.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

$clientdate = $_ENV['CLIENT_DATE'];
$cookiedata = $_ENV['COOKIE_DATA'];
$video_download_quality = $_ENV['VIDEO_DOWNLOAD_QUALITY'];
$FFMPEG_PRESENTATION_MERGE_FLAG = false;
$msg = '';

if($cookiedata == '' || $clientdate == '')
Expand All @@ -13,4 +15,4 @@
if(!extension_loaded('openssl'))
$msg .= 'Openssl not enabled in php.ini\n';
if($msg != '')
die($msg);
die($msg);
40 changes: 36 additions & 4 deletions include/downloader.functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function create_chap_folder($datas)

function chapterwise_download($datas)
{
global $contentsdata, $p, $root_project_dir;
global $contentsdata, $p, $root_project_dir, $FFMPEG_PRESENTATION_MERGE_FLAG, $video_download_quality;

$index = 1;
foreach ($datas as $data) {
Expand All @@ -57,6 +57,32 @@ function chapterwise_download($datas)
$result = query("https://" . $p['host'] . "/api/course_player/v2/html_items/" . $content['contentable']);
$temp = json_decode($result, true);
$temp2 = unicode_decode($temp["html_item"]["html_text"]); //Store Unicode Decoded HTML Code to temp2

# Find a string similar to https://platform.thinkific.com/videoproxy/v1/play/*
$regex = '/https:\/\/platform.thinkific.com\/videoproxy\/v1\/play\/[a-zA-Z0-9]+/';
preg_match_all($regex, $temp2, $matches, PREG_SET_ORDER, 0);
$first_set_matches = array_unique($matches, SORT_REGULAR);
print_r($first_set_matches);

if(empty($first_set_matches)) {
echo "No matches found. Continuing...";
} else {
foreach($first_set_matches as $match) {
echo "Here";
$video_url = $match[0];
video_downloader($video_url, $content["name"], $video_download_quality);
}
}

# Query the API for the video URL

# Find a string similar to https://fast.wistia.com/embed/medias/*.jsonp

// # FInd all iframe src links which contain https://platform.thinkific.com/videoproxy/v1/play/*
// $regex = '/<iframe.*?src="(https:\/\/platform.thinkific.com\/videoproxy\/v1\/play\/[a-zA-Z0-9]+)".*?<\/iframe>/';
// preg_match_all($regex, $temp2, $matches, PREG_SET_ORDER, 0);
// $matches = array_unique($matches, SORT_REGULAR);
// print_r($matches);
$fname = str_replace(" ","-",$fname);
$myfile = fopen($fname, "w");
fwrite($myfile, $temp2);
Expand Down Expand Up @@ -123,8 +149,14 @@ function chapterwise_download($datas)
*/
$vname = filter_filename($content['name']);
echo "Downloading Video : " . $vname . PHP_EOL;
$sendurl = "https://" . $p['host'] . "/api/course_player/v2/lessons/" . $content['contentable'] . "/download";
fdownload($sendurl, $vname);
$sendurl = "https://" . $p['host'] . "/api/course_player/v2/lessons/" . $content['contentable'];
$query_result = query($sendurl);
$temp = json_decode($query_result, true);
// $vid_location = $temp["videos"][0]["storage_location"];
$wistia_id = $temp["videos"][0]["identifier"];
$wistia_player_url = "https://platform.thinkific.com/videoproxy/v1/play/".$wistia_id;
video_downloader($wistia_player_url, $vname, $video_download_quality);
// fdownload($sendurl, $vname);
// save page content along with the Video
$html_fileName = $vname . ".html";
file_put_contents($html_fileName, $temp["lesson"]["html_text"]);
Expand Down Expand Up @@ -246,7 +278,7 @@ function chapterwise_download($datas)
echo "Merged PPT Video already exists. Skipping. ".$dc.PHP_EOL;
}

if($MULTIPURPOSE_FLAG == true){
if($MULTIPURPOSE_FLAG == true && $FFMPEG_PRESENTATION_MERGE_FLAG == true){

// Download Image and Audio files
echo "Downloading Images and Audio files".PHP_EOL;
Expand Down
48 changes: 48 additions & 0 deletions include/wistia.downloader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

function video_downloader($video_url, $file_name, $quality = "720p") {
$video_html_frame = query($video_url);
# Find a string similar to https://fast.wistia.com/embed/medias/*.jsonp
preg_match('/https:\/\/fast.wistia.com\/embed\/medias\/[a-zA-Z0-9]+.jsonp/', $video_html_frame, $video_data);
if(!empty($video_data)) {
# Choose the first match
$video_data = $video_data[0];
$video_json_data = file_get_contents($video_data);

$extract_video_json = [];
preg_match('/\{.*\}/s', $video_json_data, $extract_video_json);

if(!empty($extract_video_json)) {
# Decode the JSON data
$final_video_data = json_decode($extract_video_json[0], true);

# Get the video url by display_name in the list of assets
$video_assets = $final_video_data["media"]["assets"];
$video_assets_count = count($video_assets);
$video_assets_index = 0;
$video_assets_found = false;
while($video_assets_index < $video_assets_count) {
if($video_assets[$video_assets_index]["display_name"] == $quality) {
$video_assets_found = true;
break;
}
$video_assets_index++;
}

if(!$video_assets_found) {
echo "Video quality not found. Downloading the default quality video.".PHP_EOL;
$video_assets_index = 0;
}

$full_hd_url = $video_assets[$video_assets_index]["url"];
if($final_video_data["media"]["assets"][$video_assets_index]["ext"] == "")
$file_name = $file_name.".mp4";
else
$file_name = $file_name.".".$final_video_data["media"]["assets"][$video_assets_index]["ext"];

# Download the video
downloadFileChunked($full_hd_url, $file_name);
}
}

}
5 changes: 3 additions & 2 deletions thinkidownloader3.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
require("config.php");
$pwd = '';
$root_project_dir = '';
$revision = "Revision 6.2 ~ 3rd March 2023";
$revision = "Revision 6.3 ~ 4th November 2023";

error_reporting(0); //Disabled for keeping console clean. Set to 1 if you got an error or problem while downloading :)
echo "THINKIFIC DOWNLOADER".PHP_EOL.$revision.PHP_EOL."Author : SumeetWeb ~ https://github.com/sumeetweb".PHP_EOL."Consider buying me a coffee at : https://www.ko-fi.com/sumeet".PHP_EOL."Thinki-Parser Experimental is available for testing!".PHP_EOL;
echo "THINKIFIC DOWNLOADER".PHP_EOL.$revision.PHP_EOL."Author : SumeetWeb ~ https://github.com/sumeetweb".PHP_EOL."Consider buying me a coffee at : https://www.ko-fi.com/sumeet".PHP_EOL."Want to download only selected videos? Thinki-Parser Experimental is available!".PHP_EOL;
echo "----------------------------------------------------------".PHP_EOL;
require("include/file.functions.php");
require("include/downloader.functions.php");
require("include/wistia.downloader.php");

// Run.
// If --json, then read from json file.
Expand Down