Purchase access to watch this video.

Unlock course for £159

Already purchased access? Login

List videos on the front-end website

  1. Administrators can upload and publish videos, so it would be nice if users can
  2. view and watch these videos.
  3. We'll therefore now move on to building the front end of our website.
  4. Earlier we created an admin video controller.
  5. We now go to create a regular video controller.
  6. Run " sail artisan make:controller VideoController",
  7. and pass "videos" as the model argument.
  8. Open it up and delete all actions except the "index" and the "store" action.
  9. In the "index" action we want to fetch the latest published videos.
  10. If we open up our Video model we can define a new local scope to only return
  11. its published videos.
  12. We can now use this published local scope in our query.
  13. And we can return the results in a videos index view.
  14. Create that view.
  15. Open up our admin videos index view and copy the contents.
  16. We'll paste the contents.
  17. If you go to the browser and to /videos we'll get a 404 Not Found.
  18. That's because we've not registered the routes yet.
  19. In your routes/web.php file, register a new resource route for videos.
  20. Now we've already imported the video controller from the admin namespace, so I'm
  21. going to update this import and alias it.
  22. Instead of importing it as "VideoController" I'm going to import it as
  23. "AdminVideoController".
  24. And we're going to alias it here.
  25. This way we can now import the front end videos controller as just
  26. VideoController.
  27. And we only have the "index" and "show" methods. If we refresh in the browser
  28. we can now see the admin view.
  29. This isn't very appealing, so let's instead display video in cards like you
  30. might find on YouTube or Netflix.
  31. I've used Tailwind styles to create some cards and also display the pagination
  32. links like we were in the admin panel.
  33. And the layout now looks like this.
  34. For each video we'll see a card with a video title, the video duration, and a
  35. thumbnail.
  36. However, we just have a blank space where the thumbnail video should be at the
  37. moment.
  38. When we uploaded videos, we set the policy to "signed".
  39. This means that we need to authorize requests for anything related to the video
  40. included thumbnail URLs.
  41. The Mux Docs has a section on getting images from a video, including how to do
  42. so using signed URLs.
  43. The Mux docs has a section on getting the images from a video, including how to
  44. do so with signed URLs.
  45. Signed URLs are just URLs with a JSON web token or JWT added to the query string.
  46. This JWT will be created by our application using a secret key given to us by
  47. Mux.
  48. Mux will then verify that JWT is valid, and if it is, we will be able to view
  49. the video thumbnail.
  50. The first step to be able to create JWTs is to get our signing keys from Mux.
  51. Go to your Mux dashboard.
  52. Go to "Settings", "Signing Keys".
  53. Click the "Generate new key" button.
  54. Leave the environment as default, and click "Generate signing key".
  55. It's important you stay on this page as the secret won't be shown again.
  56. First, copy the "signing key ID".
  57. Open up your .env file.
  58. And paste this into a new environment variable called "MUX_SIGNING_KEY_ID".
  59. Copy the Base64-encoded private key.
  60. And paste that into a "MUX_SIGNING_SECRET" environment variable.
  61. Wrap it in quotes, and save the file.
  62. Again, we'll need to map these to configuration keys.
  63. Create a key for "signing_key_id".
  64. Reference the environment variables we just created.
  65. We now have the keys needed to create JWTs.
  66. We'll now install a package to help with the creation of the JWTs themselves.
  67. Install the firebase/php-jwt package.
  68. Now create a new folder called "App\Services\Mux".
  69. Inside the directory, create a new file called "JwtFactory.php".
  70. While working with third-party services such as Mux,
  71. I like to keep all classes related to that service inside its own directory.
  72. Inside the file, add a constructor.
  73. The constructor should take two string arguments, a key, and a secret.
  74. These should mapped to properties.
  75. These are going to be the signing key ID and signing secret we just got
  76. from Mux and added to our application.
  77. To provide values for these arguments, we can again use the service container.
  78. Open your MuxServiceProvider file.
  79. Add a new binding for the JwtFactory we just created.
  80. When instantiating the class, we can provide the values from our services
  81. configuration file as the key and secret values.
  82. Now when we resolve this class from the container, it will be correctly instantiated
  83. with the signing key ID and signing secret.
  84. Back in the JwtFactory class, let's add a protected "create" method.
  85. It's going to accept a payload array, and it's going to return a string.
  86. If we visit the "Secure video playback" section of the Mux docs and head to the
  87. "Sign the JSON Web Token" section,
  88. we'll see that Mux again provides a helpful PHP example.
  89. We can see that the payload needs a "kid" property.
  90. This needs setting to the signing key ID and that the secret is Base64
  91. decoded and passed as a second parameter.
  92. We made the "create" method in our JwtFactory protected because we can create
  93. other methods that delegate to this method.
  94. We'll be starting with video thumbnails.
  95. Define a new public method in the class called "thumbnail",
  96. the method should take a Video model instance, and it's going to return the
  97. JSON string.
  98. If we go back to the Mux docs, we see that the example shows create in the
  99. payload for a thumbnail, so we can use this.
  100. We'll take the payload, paste it in our "thumbnail" method,
  101. de-reference the "mux_playback_id" attribute from the Video model,
  102. and remove this in the parameters as we don't need them at the moment.
  103. In the "create" method, we'll merge a new array with the payload array,
  104. setting the "kid" to the key in the class.
  105. We'll now copy the method to create the JWT and instead return the value,
  106. making sure to import the Firebase JWT class.
  107. We now have a class to generate a JWT for a thumbnail of a particular video,
  108. but it's going to be quite cumbersome to use.
  109. To help, we'll create a custom facade.
  110. Inside the "App\Services\Mux" directory, create a new directory called "Facades".
  111. Inside this directory, create a new "JWT.php" file,
  112. and extend Laravel's abstract Facade class.
  113. Inside the class, we need to define a protected, static, "getFacadeAccessor"
  114. method
  115. and this method should just return the key of a service container binding.
  116. We want to reference our "JwtFactory" class, which we just bound to the class
  117. name
  118. so we can just return the class name.
  119. If we go back to our front-end video listing,
  120. we can now define the src of our img tags to be the thumbnail URL for
  121. videos.
  122. Back in the Mux docs, we can see the base URL for thumbnails
  123. and then then we pass the JWT as a "token" parameter in the query string.
  124. So let's copy this,
  125. paste in the img src attribute,
  126. use "$video->mux_playback_id",
  127. specify format as "jpg" for maximum compatibility,
  128. and for the JWT, we need to generate it inline.
  129. We call a thumbnail method, and we pass the video as a parameter.
  130. If we refresh the video listing, we'll see that we actually get an error.
  131. It's complaining that the JwtFactory class,
  132. the first argument key must be of type string, but we're passing null.
  133. Let's take a look at what's going on in our MuxServiceProvider class.
  134. So we should be passing the key from the configuration file.
  135. We'll see I'm using "services.jwt".
  136. This is actually a typo.
  137. This should be "mux".
  138. If we go back to the videos listing and refresh,
  139. we can now see the thumbnail coming back from Mux.
  140. In the next video, we'll go about actually creating the details view for a
  141. video
  142. and actually playing the video on the browser.
Connect GitHub