Building a YouTube LTI app
If you didn't know, I'm a fan of LTI. What is LTI? It's a cross-platform standard in edtech for what essentially amounts to Facebook apps for learning. Like Bejeweled Blitz running within Facebook, you now have Quizlet flashcards running with a course web site. It's pretty slick, and it makes it a lot easier to build apps that work in different learning platforms.
Anyway. I thought I'd start sharing some examples of LTI apps and how they could be built. I'll start with an app to embed YouTube videos within course content. The server code is ruby-esque pseudocode which hopefully is grok-able. I've included an actual ruby app at the end as well for reference.
For this example I'll use the standard LTI workflow (Canvas has what I think is a cleaner workflow, but it's not officially supported right now. I'll cover that in another post). With LTI, the teacher or administrator sets up an LTI app. They specify a
App "launches" happen when a user accesses the app from its placement within the learning platform. A launch consists of a client-side form post with an iframe or new tab as the form target. A bunch of data gets sent as POST parameters, including an OAuth-style signature derived from the parameters, key and secret. For simplicity (and since we're just dealing with public videos and don't care if the user is actually authenticated) we're going to ignore signature verification this time around. In a production environment I'd add the check or someone could potentially stuff your database with garbage data.
The only values we're going to worry about are
Now we need to build the YouTube video selection page. I like jQuery, and YouTube supports jsonp, so the querying part is actually pretty easy. For the sake of simplicity we're going to build an "I'm feeling lucky" YouTube searcher that just assumes the first result is the one you want.
We also need a server-side piece to persist the placement_id-to-video mapping to the db.
Now the first person to launch the YouTube app after it's been placed will see the search interface that will let them specify which video to show, and anyone who launches the app after that will get redirected to the selected video.
Sinatra app source code available here.
LTI was originally called BLTI, which always made me hungry. |
Anyway. I thought I'd start sharing some examples of LTI apps and how they could be built. I'll start with an app to embed YouTube videos within course content. The server code is ruby-esque pseudocode which hopefully is grok-able. I've included an actual ruby app at the end as well for reference.
For this example I'll use the standard LTI workflow (Canvas has what I think is a cleaner workflow, but it's not officially supported right now. I'll cover that in another post). With LTI, the teacher or administrator sets up an LTI app. They specify a
launch URL
, a consumer key
and a shared secret
. Then when anyone clicks a link to access the app, it will be loaded in an iframe within the platform. In our case, the teacher would add one or more YouTube App placeholders to their course content. Then the teacher would go to each of these placeholders and specify which YouTube video to associate with each placement. Students who launch the app after it is set up will just see the selected YouTube video.App "launches" happen when a user accesses the app from its placement within the learning platform. A launch consists of a client-side form post with an iframe or new tab as the form target. A bunch of data gets sent as POST parameters, including an OAuth-style signature derived from the parameters, key and secret. For simplicity (and since we're just dealing with public videos and don't care if the user is actually authenticated) we're going to ignore signature verification this time around. In a production environment I'd add the check or someone could potentially stuff your database with garbage data.
# Handle POST requests to the endpoint "/lti_launch" post "/lti_launch" do # do magical YouTube-y stuff end
The only values we're going to worry about are
resource_link_id
and tool_consumer_instance_guid
. The combination of these values should give us a globally unique identifier that we can use to remember this "launch". We'll call this the placement_id
, and since any launch from the same placement will result in the same placement_id
, we can use it to remember which video the teacher picked for this placement. If the teacher adds multiple YouTube App placeholders to their course, each placeholder will launch with a different resource_link_id
(tool_consumer_instance_guid
is an extra precaution in case platforms use the same link id) and result in a different placement_id
.# Handle POST requests to the endpoint "/lti_launch" post "/lti_launch" do placement_id = params['resource_link_id'] + params['tool_consumer_instance_guid'] placement = find_placement(placement_id) if placement redirect_to "https://youtube.com/embed/" + placement.video_id else # use a cookie-based session to remember placement permission session["can_set_" + placement_id] = true # let the user pick the video to use for this placement
redirect_to ("/youtube_search.html?placement_id=" + placement_id)
end end
Now we need to build the YouTube video selection page. I like jQuery, and YouTube supports jsonp, so the querying part is actually pretty easy. For the sake of simplicity we're going to build an "I'm feeling lucky" YouTube searcher that just assumes the first result is the one you want.
<html> <body> <h1>YouTube Searcher</h1> <p>Search for a YouTube video below. The first result is what will be shown whenever anyone loads this app. </p> <form id="form"> <input type="text" name="query" id="query"/> <button type="submit">I'm Feeling Lucky</button> </form> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <script> // Remember the placement_id so we can persist one a video is found var placement_id = location.href.match(/placement_id=([^&#]+)/)[1]; // AJAX call to remember the placement for future launches function rememberVideo(video_id) { $.ajax({ url: "/set_video", type: 'POST', data: { placement_id: placement_id, video_id: video_id }, success: function(data) { if(data.success) { alert("Video set! Redirecting now..."); location.href = "https://www.youtube.com/embed/" + video_id; } else { alert("There was a problem setting the video."); } }, dataType: 'json' }); } // JSONP call to search for YouTube videos function findVideo(query) { // YouTube API endpoint. var url = "https://gdata.youtube.com/feeds/api/videos?v=2&q=";
url = url + query + "&orderby=relevance&alt=json-in-script";
$.ajax({ url: url, success: function(data) { // Grad the *first* video and use that one. // If you wanted to list the videos instead this would be the place to // iterate through the results. The attribute names are... different, // but you can find thumbnails, descriptions, durations, etc. var video_id = data.feed.entry[0].id['$t'].match(/\w+$/)[0]; rememberVideo(video_id); }, dataType: 'jsonp' }); } // When the user submits the search form, trigger the JSONP lookup $("#form").submit(function(event) { event.preventDefault(); findVideo($("#query").val()); }); </script> </body> </html>
We also need a server-side piece to persist the placement_id-to-video mapping to the db.
# Handle POST requests to the endpoint "/set_video" post "/set_video" do if session["can_set_" + params['placement_id']] create_placement(params['placement_id'], params['video_id']) return '{"success": true}'
else
return '{"success": false}' end end
Now the first person to launch the YouTube app after it's been placed will see the search interface that will let them specify which video to show, and anyone who launches the app after that will get redirected to the selected video.
Sinatra app source code available here.
Comments
Regards,
function findVideo(query) {
// YouTube API endpoint.
var url = "https://www.googleapis.com/youtube/v3/search?&q=" + query + "&order=relevance&part=snippet";
Emma Gamer Girl
Thanks
I'm new to Canvas. Recently I'm created small website it contains userid, user progress and all user data. I'm done frontend application now i want to access that canvas data. I'm added website in canvas through LTI app. just tell me how to access username and user details using LTI variable. please give sample example
Thanks
Very Informative blog thank you for sharing. Keep sharing.
Best software training institute in Chennai. Make your career development the best by learning software courses.
devops training in chennai
rpa training in chennai
cloud computing training in chennai
recognize that other people online have the identical fervor like mine
to grasp great deal more around this condition.
dot net training institute in chennai
core java course in chennai
Manual Testing Training institute in Chennai