Exporter des fichiers vers YouTube en .NET C# avec l’open source
Exporter des vidéos vers YouTube par programmation est essentiel pour automatiser la gestion des contenus vidéo. Ce guide utilise la bibliothèque cliente .NET open source officielle de Google pour téléverser des vidéos via l’API YouTube Data depuis une application de bureau ou en ligne de commande, avec autorisation de l’utilisateur, suivi de la progression et gestion des erreurs.
Prérequis
- .NET 6.0 ou version ultérieure
- Projet Google Cloud avec l’API YouTube Data activée
- Informations d’identification OAuth 2.0 de type Desktop app provenant de Google Cloud Console
(téléchargez votre fichier
client_secrets.json), avec un écran de consentement OAuth et un utilisateur de test autorisé, le cas échéant - Package NuGet Google.Apis.YouTube.v3
Configurer le client de l’API YouTube
Commencez par installer le package NuGet requis :
dotnet add package Google.Apis.YouTube.v3 --version 1.76.0.4262
Utilisez la méthode de fabrique suivante pour créer une instance du service YouTube. La première
autorisation ouvre un navigateur pour que le propriétaire de la chaîne puisse accorder l’accès.
Les téléversements vers YouTube nécessitent des informations d’identification OAuth utilisateur ;
les comptes de service ne peuvent pas remplacer ce processus. Le répertoire des jetons stocke les jetons
d’actualisation et doit être accessible uniquement à l’utilisateur de l’application. Les deux blocs
de classe partial ci-dessous appartiennent au même projet.
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Upload;
using Google.Apis.YouTube.v3;
using Google.Apis.Util.Store;
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
public partial class YouTubeUploader : IDisposable
{
private readonly YouTubeService _youtubeService;
private YouTubeUploader(YouTubeService youtubeService)
{
_youtubeService = youtubeService;
}
public static async Task<YouTubeUploader> CreateAsync(string credentialsPath, string tokenDirectory)
{
using var stream = File.OpenRead(credentialsPath);
var clientSecrets = GoogleClientSecrets.FromStream(stream).Secrets;
var credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
clientSecrets,
new[] { YouTubeService.Scope.YoutubeUpload },
"channel-owner",
CancellationToken.None,
new FileDataStore(tokenDirectory, true));
var youtubeService = new YouTubeService(new BaseClientService.Initializer
{
HttpClientInitializer = credential,
ApplicationName = "YOUR_APP_NAME"
});
return new YouTubeUploader(youtubeService);
}
public void Dispose() => _youtubeService.Dispose();
}
Téléverser des vidéos
La méthode ci-dessous gère les téléversements de vidéos avec un suivi de la progression et une gestion complète des erreurs :
using System;
using System.IO;
using System.Threading.Tasks;
using Google.Apis.Upload;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
public partial class YouTubeUploader
{
public async Task<string> UploadVideoAsync(
string filePath,
string title,
string description,
string[] tags,
IProgress<IUploadProgress>? progress = null)
{
var video = new Video
{
Snippet = new VideoSnippet
{
Title = title,
Description = description,
Tags = tags,
CategoryId = "22" // People & Blogs category
},
Status = new VideoStatus
{
PrivacyStatus = "private" // or "public", "unlisted"
}
};
using var fileStream = File.OpenRead(filePath);
var videosInsertRequest = _youtubeService.Videos.Insert(
video,
"snippet,status",
fileStream,
"video/*");
videosInsertRequest.ChunkSize = ResumableUpload.MinimumChunkSize;
if (progress != null)
{
videosInsertRequest.ProgressChanged += progress.Report;
}
try
{
var uploadResponse = await videosInsertRequest.UploadAsync();
uploadResponse.ThrowOnFailure();
if (uploadResponse.Status != UploadStatus.Completed ||
string.IsNullOrEmpty(videosInsertRequest.ResponseBody?.Id))
{
throw new InvalidOperationException("Video upload did not complete.");
}
return videosInsertRequest.ResponseBody.Id;
}
catch (Google.GoogleApiException ex) when (ex.Error != null &&
(ex.Error.Code == 403 || ex.Error.Code == 429 || ex.Error.Code == 503))
{
throw new InvalidOperationException("YouTube rejected the upload. Check channel access, project quota, and service availability.", ex);
}
finally
{
if (progress != null) videosInsertRequest.ProgressChanged -= progress.Report;
}
}
}
Gérer les quotas et les limites de débit
Consultez les limites de votre projet et la
documentation actuelle des quotas YouTube
avant de définir un budget local. Les téléversements disposent de leur propre enveloppe de quota,
et les quotas quotidiens sont réinitialisés à minuit, heure du Pacifique. Le mécanisme de protection
suivant limite la concurrence et réserve un budget configurable avant chaque opération, y compris
les tentatives qui échouent. Partagez une instance par enveloppe au sein d’un processus.
Ce mécanisme fonctionne en mémoire ; les redémarrages, les nouvelles tentatives du SDK et les autres
instances de l’application nécessitent donc toujours une surveillance centralisée des quotas.
Transmettez le coût actuel de l’opération via quotaCost.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
public class QuotaManager : IDisposable
{
private readonly SemaphoreSlim _uploadSemaphore;
private readonly Dictionary<DateTime, int> _quotaUsage;
private readonly int _dailyLimit;
private readonly TimeZoneInfo _quotaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
public QuotaManager(int dailyLimit, int maxConcurrentUploads = 3)
{
if (dailyLimit <= 0 || maxConcurrentUploads <= 0) throw new ArgumentOutOfRangeException();
_dailyLimit = dailyLimit;
_uploadSemaphore = new SemaphoreSlim(maxConcurrentUploads);
_quotaUsage = new Dictionary<DateTime, int>();
}
public async Task<T> ExecuteWithQuotaAsync<T>(
Func<Task<T>> operation,
int quotaCost)
{
if (quotaCost <= 0 || quotaCost > _dailyLimit) throw new ArgumentOutOfRangeException(nameof(quotaCost));
await _uploadSemaphore.WaitAsync();
try
{
lock (_quotaUsage)
{
var today = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, _quotaTimeZone).Date;
if (!_quotaUsage.ContainsKey(today))
{
_quotaUsage.Clear();
_quotaUsage[today] = 0;
}
if (quotaCost > _dailyLimit - _quotaUsage[today])
{
throw new InvalidOperationException("Daily upload budget would be exceeded");
}
_quotaUsage[today] += quotaCost;
}
return await operation();
}
finally
{
_uploadSemaphore.Release();
}
}
public void Dispose() => _uploadSemaphore.Dispose();
}
Bonnes pratiques pour une utilisation en production
- Implémentez une logique de nouvelle tentative avec délai exponentiel pour gérer les erreurs transitoires, comme les problèmes réseau ou les limites de débit temporaires.
- Stockez vos informations d’identification de manière sécurisée pour protéger vos secrets OAuth 2.0.
- Surveillez la progression des téléversements pour fournir un retour et diagnostiquer les problèmes en temps réel.
- Assurez une gestion robuste des erreurs couvrant les dépassements de quota, les échecs d’authentification et les contraintes de taille de fichier ou de réseau.
Implémenter une logique de nouvelle tentative
Le SDK gère les nouvelles tentatives de téléversement avec reprise. Utilisez la fonction utilitaire
ci-dessous uniquement pour les opérations qui peuvent être répétées sans risque, comme les requêtes
de lecture. Relancer une opération videos.insert entière peut créer des vidéos en
double si le premier téléversement a réussi, mais que sa réponse a été perdue.
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Google;
public class RetryExamples
{
public async Task<T> RetryWithExponentialBackoff<T>(
Func<Task<T>> operation,
int maxAttempts = 3)
{
if (maxAttempts <= 0) throw new ArgumentOutOfRangeException(nameof(maxAttempts));
for (int attempt = 1; attempt <= maxAttempts; attempt++)
{
try
{
return await operation();
}
catch (Exception ex) when (IsTransientException(ex))
{
if (attempt == maxAttempts) throw;
var delay = TimeSpan.FromSeconds(Math.Pow(2, attempt));
await Task.Delay(delay);
}
}
throw new Exception("Retry attempts exhausted");
}
private bool IsTransientException(Exception ex)
{
return ex is HttpRequestException ||
(ex is GoogleApiException gex && (gex.Error?.Code == 429 || gex.Error?.Code == 503));
}
}
Stocker les informations d’identification de manière sécurisée
Configurez YOUTUBE_CREDENTIALS_PATH dans l’environnement de votre processus pour pointer vers
le fichier JSON du client de bureau téléchargé. Excluez ce fichier et le répertoire des jetons du
contrôle de version, restreignez les accès au système de fichiers et utilisez un service géré de
stockage des secrets pour les déploiements hébergés. Cette fonction utilitaire localise uniquement
le fichier ; elle ne chiffre pas les informations d’identification. Les applications web nécessitent
le processus OAuth côté serveur de Google plutôt que le processus avec navigateur pour application de bureau
présenté ici.
using System;
public class SecureCredentialManager
{
public string GetCredentialsPath()
{
var path = Environment.GetEnvironmentVariable("YOUTUBE_CREDENTIALS_PATH");
if (string.IsNullOrEmpty(path))
{
throw new InvalidOperationException("YOUTUBE_CREDENTIALS_PATH is not configured");
}
return path;
}
}
Surveiller la progression des téléversements
using System;
using Google.Apis.Upload;
public class UploadProgressHandler : IProgress<IUploadProgress>
{
public void Report(IUploadProgress progress)
{
var status = progress.Status switch
{
UploadStatus.Uploading => $"Uploading: {progress.BytesSent} bytes sent",
UploadStatus.Failed => "Upload failed",
UploadStatus.Completed => "Upload completed",
_ => $"Status: {progress.Status}"
};
Console.WriteLine(status);
}
}
Conclusion
L’exportation de fichiers vers YouTube en .NET C# nécessite des pratiques d’authentification à jour, une gestion rigoureuse des quotas et une gestion robuste des erreurs. En intégrant la bibliothèque cliente des API Google avec un chargement asynchrone des informations d’identification et en suivant les bonnes pratiques pour les déploiements en production, vous pouvez créer une solution résiliente de téléversement de vidéos. Pour simplifier la gestion des exportations de fichiers et du traitement vidéo à grande échelle, envisagez d’utiliser le service d’exportation de fichiers de Transloadit.
