Purchase access to watch this video.

Unlock course for £159

Already purchased access? Login

List videos on the front-end website

Connect GitHub

Transcript was automatically generated and may be inaccurate.

  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.