PHPackages                             janwebdev/symfony-social-video-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. janwebdev/symfony-social-video-bundle

ActiveSymfony-bundle

janwebdev/symfony-social-video-bundle
=====================================

Symfony bundle for posting short videos (Reels/Shorts) to YouTube, Instagram, Facebook, X/Twitter, Threads, and TikTok

1.0.0(3d ago)00MITPHPPHP &gt;=8.4

Since Mar 21Pushed 3d agoCompare

[ Source](https://github.com/janwebdev/symfony-social-video-bundle)[ Packagist](https://packagist.org/packages/janwebdev/symfony-social-video-bundle)[ RSS](/packages/janwebdev-symfony-social-video-bundle/feed)WikiDiscussions master Synced today

READMEChangelog (1)Dependencies (9)Versions (2)Used By (0)

Symfony Social Video Bundle
===========================

[](#symfony-social-video-bundle)

[![Latest Stable Version](https://camo.githubusercontent.com/119cbb0b0db9b66d58eec7aef5f40e33268359b1a3ac5731212d93ac8d9ac895/68747470733a2f2f706f7365722e707567782e6f72672f6a616e7765626465762f73796d666f6e792d736f6369616c2d766964656f2d62756e646c652f76657273696f6e)](https://packagist.org/packages/janwebdev/symfony-social-video-bundle)[![Total Downloads](https://camo.githubusercontent.com/d083f88e7d85ed636792bde3854db22150322437fbaa63b45dedc7039cf77488/68747470733a2f2f706f7365722e707567782e6f72672f6a616e7765626465762f73796d666f6e792d736f6369616c2d766964656f2d62756e646c652f646f776e6c6f616473)](https://packagist.org/packages/janwebdev/symfony-social-video-bundle)[![License](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](LICENSE)[![PHP](https://camo.githubusercontent.com/ededbf25fccb0dfe09e175a8dbfe5842db89f2d70523c852dc897cd1890f7eb2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e342532422d707572706c65)](https://php.net)[![Symfony](https://camo.githubusercontent.com/9757b5be2d8782cae8a4e16c23f19151d2b1360355317b24c5fee456a7c444e0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53796d666f6e792d372e342532422d677265656e)](https://symfony.com)

Symfony bundle for posting short videos (Reels/Shorts) to social networks.

✨ Features
----------

[](#-features)

- 🎬 **6 Platforms**: YouTube Shorts, Instagram Reels, Facebook Reels, X/Twitter, Threads, TikTok
- 📁 **Flexible Sources**: Local files or public URLs (platform-dependent)
- ⚡ **Async Support**: Symfony Messenger integration
- 🎯 **Type Safe**: PHP 8.4 readonly properties throughout
- 🔄 **No External SDK**: All API clients built-in
- 📝 **Fluent API**: `VideoMessageBuilder` for easy video post creation
- 🎪 **Event System**: Before/After/Failed publish events

📦 Installation
--------------

[](#-installation)

```
composer require janwebdev/symfony-social-video-bundle
```

Register the bundle in `config/bundles.php`:

```
return [
    // ...
    Janwebdev\SocialVideoBundle\SocialVideoBundle::class => ['all' => true],
];
```

⚙️ Configuration
----------------

[](#️-configuration)

Create `config/packages/social_video.yaml`:

```
social_video:
  providers:
    youtube:
      enabled: true
      access_token: "%env(YOUTUBE_ACCESS_TOKEN)%"
      privacy_status: "public"          # public | private | unlisted

    instagram:
      enabled: true
      account_id: "%env(INSTAGRAM_ACCOUNT_ID)%"
      access_token: "%env(INSTAGRAM_ACCESS_TOKEN)%"
      graph_version: "v22.0"

    facebook:
      enabled: true
      page_id: "%env(FACEBOOK_PAGE_ID)%"
      access_token: "%env(FACEBOOK_ACCESS_TOKEN)%"
      graph_version: "v22.0"

    twitter:
      enabled: true
      api_key: "%env(TWITTER_API_KEY)%"
      api_secret: "%env(TWITTER_API_SECRET)%"
      access_token: "%env(TWITTER_ACCESS_TOKEN)%"
      access_token_secret: "%env(TWITTER_ACCESS_TOKEN_SECRET)%"

    threads:
      enabled: true
      user_id: "%env(THREADS_USER_ID)%"
      access_token: "%env(THREADS_ACCESS_TOKEN)%"
      # NOTE: Threads API requires a public video URL — local files are not supported.

    tiktok:
      enabled: true
      client_key: "%env(TIKTOK_CLIENT_KEY)%"
      access_token: "%env(TIKTOK_ACCESS_TOKEN)%"
      # NOTE: Requires video.publish scope approval from TikTok. Until approved,
      # all videos are posted as private (SELF_ONLY).
```

### Environment Variables

[](#environment-variables)

```
# YouTube Data API v3
YOUTUBE_ACCESS_TOKEN=ya29.your_oauth_token

# Instagram Graph API (Business/Creator account required)
INSTAGRAM_ACCOUNT_ID=your_ig_business_account_id
INSTAGRAM_ACCESS_TOKEN=your_page_access_token

# Facebook Graph API (Page token with publish_video permission)
FACEBOOK_PAGE_ID=your_page_id
FACEBOOK_ACCESS_TOKEN=your_page_access_token

# X/Twitter API v2 (OAuth 1.0a)
TWITTER_API_KEY=your_api_key
TWITTER_API_SECRET=your_api_secret
TWITTER_ACCESS_TOKEN=your_access_token
TWITTER_ACCESS_TOKEN_SECRET=your_access_token_secret

# Threads API
THREADS_USER_ID=your_threads_user_id
THREADS_ACCESS_TOKEN=your_threads_access_token

# TikTok Content Posting API v2
TIKTOK_CLIENT_KEY=your_client_key
TIKTOK_ACCESS_TOKEN=your_access_token
```

🚀 Usage
-------

[](#-usage)

### Basic Usage

[](#basic-usage)

```
use Janwebdev\SocialVideoBundle\Message\VideoMessageBuilder;
use Janwebdev\SocialVideoBundle\Publisher\VideoPublisher;

class YourService
{
    public function __construct(private VideoPublisher $publisher) {}

    public function postVideo(): void
    {
        $message = VideoMessageBuilder::create()
            ->setVideoPath('/path/to/reel.mp4')          // local file
            // OR: ->setVideoUrl('https://cdn.example.com/reel.mp4')
            ->setTitle('My Amazing Short #Shorts')
            ->setDescription('Check this out!')
            ->addHashtag('reels')
            ->addHashtag('fyp')
            ->setPrivacy('public')
            ->forNetworks(['youtube', 'instagram', 'tiktok'])
            ->build();

        $results = $this->publisher->publish($message);

        foreach ($results as $result) {
            if ($result->isSuccess()) {
                echo "{$result->getProviderName()}: {$result->getPostUrl()}\n";
            } else {
                echo "Failed: {$result->getErrorMessage()}\n";
            }
        }
    }
}
```

### Async Publishing (requires symfony/messenger)

[](#async-publishing-requires-symfonymessenger)

```
// Dispatch to message queue
$this->publisher->publishAsync($message);
```

### Check Results

[](#check-results)

```
$results = $this->publisher->publish($message);

if ($results->isAllSuccessful()) {
    echo "Posted to all networks!\n";
}

$ytResult = $results->getResult('youtube');
if ($ytResult?->isSuccess()) {
    echo "YouTube URL: " . $ytResult->getPostUrl() . "\n";
}

foreach ($results->getFailed() as $result) {
    echo "Failed on {$result->getProviderName()}: {$result->getErrorMessage()}\n";
}
```

### Event Listeners

[](#event-listeners)

```
use Janwebdev\SocialVideoBundle\Publisher\Event\AfterPublishEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class VideoPostSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [AfterPublishEvent::class => 'onAfterPublish'];
    }

    public function onAfterPublish(AfterPublishEvent $event): void
    {
        foreach ($event->results->getSuccessful() as $result) {
            // Log to database, send notifications, etc.
        }
    }
}
```

📚 Platform Reference
--------------------

[](#-platform-reference)

### YouTube Shorts

[](#youtube-shorts)

- **Auth**: OAuth 2.0 user token (`YOUTUBE_ACCESS_TOKEN`)
- **Upload**: Resumable PUT upload (Google's resumable upload protocol)
- **Shorts**: Automatic classification — vertical (9:16) + ≤3 min + `#Shorts` in title/description
- **Credential setup**: [Google Cloud Console](https://console.cloud.google.com/) → Create Project → Enable YouTube Data API v3 → OAuth 2.0 credentials

### Instagram Reels

[](#instagram-reels)

- **Auth**: Page Access Token (long-lived)
- **Account**: Instagram **Business or Creator** account required
- **Upload**: Local files via rupload.facebook.com OR public video URL
- **Max duration**: 90 seconds
- **Required permissions**: `instagram_basic`, `instagram_content_publish`
- **Credential setup**: [Facebook Developers](https://developers.facebook.com/) → App → Instagram product

### Facebook Reels

[](#facebook-reels)

- **Auth**: Page Access Token with `publish_video` permission
- **Account**: Facebook **Pages** only (not personal profiles)
- **Upload**: Local binary or public URL
- **Max duration**: 60 seconds
- **Credential setup**: Same Facebook app, add `publish_video` permission

### X/Twitter

[](#xtwitter)

- **Auth**: OAuth 1.0a (`api_key`, `api_secret`, `access_token`, `access_token_secret`)
- **Upload**: Chunked INIT/APPEND/FINALIZE (5 MB chunks)
- **Max duration**: 140 seconds. Max file: 512 MB
- **Rate limit (Free tier)**: 17 upload sessions per 24 hours
- **Credential setup**: [X Developer Portal](https://developer.twitter.com/) → App → Keys &amp; Tokens

### Threads

[](#threads)

- **Auth**: Threads OAuth 2.0 user token
- **⚠️ URL only**: Threads API does not support binary upload. Use `setVideoUrl()` with a publicly accessible video URL.
- **Max duration**: 5 minutes
- **Required permissions**: `threads_basic`, `threads_content_publish`
- **Credential setup**: [Facebook Developers](https://developers.facebook.com/) → App → Threads product

### TikTok

[](#tiktok)

- **Auth**: OAuth 2.0 Bearer token
- **⚠️ Scope approval required**: `video.publish` scope requires business developer account and TikTok audit (5–10 business days). Until approved, all videos are private (`SELF_ONLY`).
- **Upload**: Local files (10 MB chunked) or public URL
- **Max duration**: 5 minutes. Rate limit: 6 init requests/min
- **Credential setup**: [TikTok for Developers](https://developers.tiktok.com/) → App → Content Posting API → Apply for `video.publish`

🧪 Testing
---------

[](#-testing)

```
# Run tests
composer run-tests

# Static analysis (PHPStan level 9)
composer run-static-analysis

# Code style check
composer check-code-style

# Fix code style
composer fix-code-style
```

📖 Upload Matrix
---------------

[](#-upload-matrix)

PlatformLocal FilePublic URLYouTube Shorts✅✅ (download first)Instagram Reels✅ (rupload)✅ (video\_url)Facebook Reels✅ (rupload)✅ (file\_url)X/Twitter✅✅ (download first)Threads❌✅ requiredTikTok✅ (chunked)✅ (PULL\_FROM\_URL)📄 License
---------

[](#-license)

MIT License. See [LICENSE](LICENSE) file.

👏 Credits
---------

[](#-credits)

Built by [Yan Rogozinsky](https://github.com/janwebdev) as part of the Symfony Social Post Bundle ecosystem.

🔗 Related
---------

[](#-related)

- [symfony-social-post-bundle](https://github.com/janwebdev/symfony-social-post-bundle) — text/image posting to the same platforms

###  Health Score

41

—

FairBetter than 89% of packages

Maintenance99

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

3d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/c883713524aa45bd05ea6b6bfae4b59807241e1d505630b4a4bdba9ef13ea7fd?d=identicon)[janwebdev](/maintainers/janwebdev)

---

Top Contributors

[![janwebdev](https://avatars.githubusercontent.com/u/6725905?v=4)](https://github.com/janwebdev "janwebdev (13 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/janwebdev-symfony-social-video-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/janwebdev-symfony-social-video-bundle/health.svg)](https://phpackages.com/packages/janwebdev-symfony-social-video-bundle)
```

###  Alternatives

[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M128](/packages/sulu-sulu)[kimai/kimai

Kimai - Time Tracking

4.6k7.2k1](/packages/kimai-kimai)[contao/core-bundle

Contao Open Source CMS

1231.6M2.1k](/packages/contao-core-bundle)[web-auth/webauthn-framework

FIDO2/Webauthn library for PHP and Symfony Bundle.

50461.3k1](/packages/web-auth-webauthn-framework)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
