List videos on the front-end website
Transcript was automatically generated and may be inaccurate.
-
–
Administrators can upload and publish videos, so it would be nice if users can -
–
view and watch these videos. -
–
We'll therefore now move on to building the front end of our website. -
–
Earlier we created an admin video controller. -
–
We now go to create a regular video controller. -
–
Run " sail artisan make:controller VideoController", -
–
and pass "videos" as the model argument. -
–
Open it up and delete all actions except the "index" and the "store" action. -
–
In the "index" action we want to fetch the latest published videos. -
–
If we open up our Video model we can define a new local scope to only return -
–
its published videos. -
–
We can now use this published local scope in our query. -
–
And we can return the results in a videos index view. -
–
Create that view. -
–
Open up our admin videos index view and copy the contents. -
–
We'll paste the contents. -
–
If you go to the browser and to /videos we'll get a 404 Not Found. -
–
That's because we've not registered the routes yet. -
–
In your routes/web.php file, register a new resource route for videos. -
–
Now we've already imported the video controller from the admin namespace, so I'm -
–
going to update this import and alias it. -
–
Instead of importing it as "VideoController" I'm going to import it as -
–
"AdminVideoController". -
–
And we're going to alias it here. -
–
This way we can now import the front end videos controller as just -
–
VideoController. -
–
And we only have the "index" and "show" methods. If we refresh in the browser -
–
we can now see the admin view. -
–
This isn't very appealing, so let's instead display video in cards like you -
–
might find on YouTube or Netflix. -
–
I've used Tailwind styles to create some cards and also display the pagination -
–
links like we were in the admin panel. -
–
And the layout now looks like this. -
–
For each video we'll see a card with a video title, the video duration, and a -
–
thumbnail. -
–
However, we just have a blank space where the thumbnail video should be at the -
–
moment. -
–
When we uploaded videos, we set the policy to "signed". -
–
This means that we need to authorize requests for anything related to the video -
–
included thumbnail URLs. -
–
The Mux Docs has a section on getting images from a video, including how to do -
–
so using signed URLs. -
–
The Mux docs has a section on getting the images from a video, including how to -
–
do so with signed URLs. -
–
Signed URLs are just URLs with a JSON web token or JWT added to the query string. -
–
This JWT will be created by our application using a secret key given to us by -
–
Mux. -
–
Mux will then verify that JWT is valid, and if it is, we will be able to view -
–
the video thumbnail. -
–
The first step to be able to create JWTs is to get our signing keys from Mux. -
–
Go to your Mux dashboard. -
–
Go to "Settings", "Signing Keys". -
–
Click the "Generate new key" button. -
–
Leave the environment as default, and click "Generate signing key". -
–
It's important you stay on this page as the secret won't be shown again. -
–
First, copy the "signing key ID". -
–
Open up your .env file. -
–
And paste this into a new environment variable called "MUX_SIGNING_KEY_ID". -
–
Copy the Base64-encoded private key. -
–
And paste that into a "MUX_SIGNING_SECRET" environment variable. -
–
Wrap it in quotes, and save the file. -
–
Again, we'll need to map these to configuration keys. -
–
Create a key for "signing_key_id". -
–
Reference the environment variables we just created. -
–
We now have the keys needed to create JWTs. -
–
We'll now install a package to help with the creation of the JWTs themselves. -
–
Install the firebase/php-jwt package. -
–
Now create a new folder called "App\Services\Mux". -
–
Inside the directory, create a new file called "JwtFactory.php". -
–
While working with third-party services such as Mux, -
–
I like to keep all classes related to that service inside its own directory. -
–
Inside the file, add a constructor. -
–
The constructor should take two string arguments, a key, and a secret. -
–
These should mapped to properties. -
–
These are going to be the signing key ID and signing secret we just got -
–
from Mux and added to our application. -
–
To provide values for these arguments, we can again use the service container. -
–
Open your MuxServiceProvider file. -
–
Add a new binding for the JwtFactory we just created. -
–
When instantiating the class, we can provide the values from our services -
–
configuration file as the key and secret values. -
–
Now when we resolve this class from the container, it will be correctly instantiated -
–
with the signing key ID and signing secret. -
–
Back in the JwtFactory class, let's add a protected "create" method. -
–
It's going to accept a payload array, and it's going to return a string. -
–
If we visit the "Secure video playback" section of the Mux docs and head to the -
–
"Sign the JSON Web Token" section, -
–
we'll see that Mux again provides a helpful PHP example. -
–
We can see that the payload needs a "kid" property. -
–
This needs setting to the signing key ID and that the secret is Base64 -
–
decoded and passed as a second parameter. -
–
We made the "create" method in our JwtFactory protected because we can create -
–
other methods that delegate to this method. -
–
We'll be starting with video thumbnails. -
–
Define a new public method in the class called "thumbnail", -
–
the method should take a Video model instance, and it's going to return the -
–
JSON string. -
–
If we go back to the Mux docs, we see that the example shows create in the -
–
payload for a thumbnail, so we can use this. -
–
We'll take the payload, paste it in our "thumbnail" method, -
–
de-reference the "mux_playback_id" attribute from the Video model, -
–
and remove this in the parameters as we don't need them at the moment. -
–
In the "create" method, we'll merge a new array with the payload array, -
–
setting the "kid" to the key in the class. -
–
We'll now copy the method to create the JWT and instead return the value, -
–
making sure to import the Firebase JWT class. -
–
We now have a class to generate a JWT for a thumbnail of a particular video, -
–
but it's going to be quite cumbersome to use. -
–
To help, we'll create a custom facade. -
–
Inside the "App\Services\Mux" directory, create a new directory called "Facades". -
–
Inside this directory, create a new "JWT.php" file, -
–
and extend Laravel's abstract Facade class. -
–
Inside the class, we need to define a protected, static, "getFacadeAccessor" -
–
method -
–
and this method should just return the key of a service container binding. -
–
We want to reference our "JwtFactory" class, which we just bound to the class -
–
name -
–
so we can just return the class name. -
–
If we go back to our front-end video listing, -
–
we can now define the src of our img tags to be the thumbnail URL for -
–
videos. -
–
Back in the Mux docs, we can see the base URL for thumbnails -
–
and then then we pass the JWT as a "token" parameter in the query string. -
–
So let's copy this, -
–
paste in the img src attribute, -
–
use "$video->mux_playback_id", -
–
specify format as "jpg" for maximum compatibility, -
–
and for the JWT, we need to generate it inline. -
–
We call a thumbnail method, and we pass the video as a parameter. -
–
If we refresh the video listing, we'll see that we actually get an error. -
–
It's complaining that the JwtFactory class, -
–
the first argument key must be of type string, but we're passing null. -
–
Let's take a look at what's going on in our MuxServiceProvider class. -
–
So we should be passing the key from the configuration file. -
–
We'll see I'm using "services.jwt". -
–
This is actually a typo. -
–
This should be "mux". -
–
If we go back to the videos listing and refresh, -
–
we can now see the thumbnail coming back from Mux. -
–
In the next video, we'll go about actually creating the details view for a -
–
video -
–
and actually playing the video on the browser.