How to Create a Video Streaming App with Laravel and Vimeo API

In this tutorial, we will learn how to create a video streaming app using the Laravel framework and Vimeo API. We will be using Laravel’s powerful features to handle user authentication, uploading videos to Vimeo, and streaming videos to our users.

Prerequisites

Before we get started, make sure you have the following prerequisites installed on your system:

  • PHP (version 7 or higher)
  • Composer
  • Laravel (version 8 or higher)
  • Vimeo API credentials (you can create a new app and get the credentials from the Vimeo Developer Dashboard)

Step 1: Set Up Laravel Project

First, let’s create a new Laravel project by running the following command in your terminal:

composer create-project laravel/laravel video-streaming-app

Once the project is created, navigate to the project directory:

cd video-streaming-app

Step 2: Configure Environment Variables

Laravel uses environment variables to store sensitive information. Open the .env file in the project root directory and add the following lines:

VIMEO_CLIENT_ID=your_client_id
VIMEO_CLIENT_SECRET=your_client_secret
VIMEO_ACCESS_TOKEN=your_access_token

Replace your_client_id, your_client_secret, and your_access_token with the actual values obtained from the Vimeo Developer Dashboard.

Step 3: Install Required Packages

To interact with the Vimeo API, we will be using the vimeo-laravel package. Install the package by running the following command:

composer require nahid/vimeo-laravel

Next, publish the package configuration file to customize its behavior:

php artisan vendor:publish --provider="NahidVimeoVimeoServiceProvider"

Step 4: Create Routes and Controllers

Before we can start building our video streaming app, let’s define the necessary routes and controllers.

Open the routes/web.php file and add the following routes:

use AppHttpControllersVideoController;

Route::get('/', [VideoController::class, 'index']);
Route::post('/videos', [VideoController::class, 'store']);

Now, let’s create the VideoController and add the required methods. In your terminal, run the following command to generate the controller:

php artisan make:controller VideoController

Open the app/Http/Controllers/VideoController.php file and replace its contents with the following code:

<?php

namespace AppHttpControllers;

use IlluminateHttpRequest;
use NahidVimeoVimeo;

class VideoController extends Controller
{
    public function index()
    {
        // Fetch the videos from Vimeo and pass them to the view
        $videos = Vimeo::request('/me/videos');

        return view('videos.index', compact('videos'));
    }

    public function store(Request $request)
    {
        // Upload the video to Vimeo
        $videoPath = $request->file('video')->getRealPath();
        $video = Vimeo::upload($videoPath);

        // Save the video details to the database
        AppModelsVideo::create([
            'vimeo_video_id' => $video['body']['uri'],
            'title' => $video['body']['name'],
        ]);

        return redirect()->route('videos.index')
            ->with('success', 'Video uploaded successfully.');
    }
}

Step 5: Create Views

Now let’s create the necessary views to display videos and to upload new videos.

Create a new directory named videos inside the resources/views directory. Inside the videos directory, create two files: index.blade.php and upload.blade.php.

In the index.blade.php file, add the following code:

@extends('layout')

@section('content')
    <h1>Videos</h1>

    @if (session('success'))
        <div class="alert alert-success">
            {{ session('success') }}
        </div>
    @endif

    <div>
        <a href="{{ route('videos.upload') }}" class="btn btn-primary">Upload Video</a>
    </div>

    <table class="table">
        <thead>
            <tr>
                <th>Title</th>
                <th>Actions</th>
            </tr>
        </thead>
        <tbody>
            @foreach ($videos['body']['data'] as $video)
                <tr>
                    <td>{{ $video['name'] }}</td>
                    <td>
                        <a href="{{ route('videos.stream', $video['uri']) }}" class="btn btn-success">Stream</a>
                    </td>
                </tr>
            @endforeach
        </tbody>
    </table>
@endsection

In the upload.blade.php file, add the following code:

@extends('layout')

@section('content')
    <h1>Upload Video</h1>

    <form method="POST" action="{{ route('videos.store') }}" enctype="multipart/form-data">
        @csrf

        <div class="form-group">
            <label for="video">Video File</label>
            <input type="file" name="video" id="video" class="form-control-file">
        </div>

        <div class="form-group">
            <button type="submit" class="btn btn-primary">Upload</button>
        </div>
    </form>
@endsection

Step 6: Create Model and Migration

We need to create a database table to store the details of uploaded videos. In your terminal, run the following command to create the model and migration file:

php artisan make:model Video -m

Open the generated migration file (located in database/migrations) and replace its contents with the following code:

<?php

use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;

class CreateVideosTable extends Migration
{
    public function up()
    {
        Schema::create('videos', function (Blueprint $table) {
            $table->id();
            $table->string('vimeo_video_id');
            $table->string('title');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('videos');
    }
}

Run the migration to create the videos table:

php artisan migrate

Step 7: Create Layout and Styling

Create a new file named layout.blade.php inside the resources/views directory and add the following code:

<!DOCTYPE html>
<html>
<head>
    <title>Video Streaming App</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container">
        @yield('content')
    </div>
</body>
</html>

Step 8: Create Streaming Route and Method

Now let’s define a route and a method in the VideoController to stream videos to our users.

Open the routes/web.php file and add the following route:

Route::get('/videos/{video}', [VideoController::class, 'stream'])->name('videos.stream');

Open the VideoController and add the stream method:

public function stream(Request $request, $videoId)
{
    $video = AppModelsVideo::where('vimeo_video_id', $videoId)->firstOrFail();

    if ($request->user()->tokenCan('view-private-videos')) {
        $streamUrl = Vimeo::request('/videos/' . $videoId . '/files')->body['data'][0]['link'];
    } else {
        $streamUrl = Vimeo::request('/videos/' . $videoId)->body['files'][0]['link'];
    }

    return view('videos.stream', compact('video', 'streamUrl'));
}

Create a new file named stream.blade.php inside the resources/views directory and add the following code:

@extends('layout')

@section('content')
    <h1>Streaming video: {{ $video->title }}</h1>

    <video width="800" height="600" controls>
        <source src="{{ $streamUrl }}" type="video/mp4">
        Your browser does not support the video tag.
    </video>
@endsection

Step 9: Set Up API Authentication

To interact with the Vimeo API, we need to set up API authentication using Laravel’s built-in OAuth2 client.

Open the app/Providers/AuthServiceProvider.php file and add the following code inside the boot method:

use LaravelPassportPassport;

Passport::tokensCan([
    'view-private-videos' => 'View private videos',
]);

Next, open the app/Http/Kernel.php file and add the following middleware to the $routeMiddleware array:

'client.credentials' => LaravelPassportHttpMiddlewareCheckClientCredentials::class,

Open the routes/api.php file and add the following route:

Route::middleware('client.credentials')->get('/videos/{video}', [VideoController::class, 'stream'])
    ->name('videos.stream');

Step 10: Update the HomeController

Open the app/Http/Controllers/HomeController.php file and update the index method to redirect to the video index page:

public function index()
{
    return redirect()->route('videos.index');
}

Step 11: Start the Development Server

That’s it! We have completed all the necessary steps to create a video streaming app with Laravel and the Vimeo API.

You can start the development server by running the following command in your terminal:

php artisan serve

Open your web browser and visit `http://localhost:8000` to see the app in action.

Conclusion

In this tutorial, we have learned how to create a video streaming app using Laravel and the Vimeo API. We have covered setting up the Laravel project, configuring environment variables, installing required packages, creating routes and controllers, creating views, setting up database migrations, creating a layout, styling the app, and implementing API authentication. Now you can expand on this foundation to build your own custom video streaming app with additional features like user profiles, playlists, and more.

Related Post