Quantcast
Channel: Active questions tagged youtube-api - Stack Overflow
Viewing all articles
Browse latest Browse all 3722

Issue with "Invalid Array Length" Error When Uploading Large Videos Using YouTube API v3

$
0
0

I am attempting to upload videos to YouTube via the YouTube API v3 from my Flutter web application. The upload process works as expected for smaller videos, but when attempting to upload a larger video (e.g., 200MB), I encounter the error: "Invalid array length," and the upload fails.

Below is the relevant portion of my code:

// Automatic FlutterFlow importsimport '/backend/backend.dart';import '/flutter_flow/flutter_flow_theme.dart';import '/flutter_flow/flutter_flow_util.dart';import '/custom_code/widgets/index.dart'; // Imports other custom widgetsimport '/custom_code/actions/index.dart'; // Imports custom actionsimport '/flutter_flow/custom_functions.dart'; // Imports custom functionsimport 'package:flutter/material.dart';// Begin custom widget code// DO NOT REMOVE OR MODIFY THE CODE ABOVE!import 'dart:async'; // For Streamimport 'dart:convert'; // For JSON decodingimport 'dart:io'    as io; // For File handling (conditionally for non-web platforms)import 'package:googleapis_auth/auth_io.dart';import 'package:googleapis/youtube/v3.dart';import 'package:file_picker/file_picker.dart';import 'dart:typed_data'; // For Uint8Listimport 'package:http/http.dart' as http;import 'package:flutter/foundation.dart'; // For kIsWebclass UploadVideoButton extends StatefulWidget {  const UploadVideoButton({    super.key,    this.width,    this.height,  });  final double? width;  final double? height;  @override  State<UploadVideoButton> createState() => _UploadVideoButtonState();}class _UploadVideoButtonState extends State<UploadVideoButton> {  bool isUploading = false;  double uploadProgress = 0.0;  // Replace these placeholders with your Google API credentials  static const String clientId = //value removed from here ;  static const String clientSecret = //value removed from here;  static const String refreshToken = //value removed from here;  static const List<String> scopes = [YouTubeApi.youtubeUploadScope];  Future<void> uploadVideo() async {    try {      setState(() {        isUploading = true;        uploadProgress = 0.0;      });      // Authenticate and get an authorized client      var authClient = await _getAuthClient();      final youtubeApi = YouTubeApi(authClient);      // Pick a video file      FilePickerResult? result = await FilePicker.platform.pickFiles(        type: FileType.video,      );      if (result != null) {        Uint8List? fileBytes = result.files.single.bytes;        //String? filePath = result.files.single.path;        // Use fileBytes for web or if path is unavailable        Uint8List fileData = fileBytes!;        // For non-web platforms, you may still want to use the file path (commented out here)        // if (filePath != null && !kIsWeb) {        //   fileData = io.File(filePath).readAsBytesSync();        // }        int totalBytes = fileData.length;        // Create byte stream compatible with YouTube API        Stream<List<int>> byteStream = Stream.fromIterable(            [fileData.buffer.asUint8List()]); // Wrap bytes into List<int>        // Progress-tracking stream        var progressStream = _createProgressStream(byteStream, totalBytes);        var video = Video();        video.snippet = VideoSnippet()          ..title = 'Sample Video Title'          ..description = 'Uploaded via Flutter App'          ..tags = ['Flutter', 'YouTube API'];        video.status = VideoStatus()..privacyStatus = 'public';        var media = Media(progressStream, totalBytes);        // Upload the video        var response = await youtubeApi.videos.insert(          video,          ['snippet', 'status'],          uploadMedia: media,        );        setState(() {          isUploading = false;        });        // Show success message        _showSnackbar('Video uploaded successfully: https://www.youtube.com/watch?v=${response.id}');      } else {        setState(() {          isUploading = false;        });        _showSnackbar('No video selected');      }    } catch (e) {      setState(() {        isUploading = false;      });      _showSnackbar('Error: $e');    }  }  Stream<List<int>> _createProgressStream(      Stream<List<int>> sourceStream, int totalBytes) {    int bytesSent = 0;    const chunkSize = 256 * 1024; // 256 KB per chunk (adjust as necessary)    return sourceStream.asyncMap((chunk) async {      bytesSent += chunk.length;      // Update progress      setState(() {        uploadProgress = bytesSent / totalBytes;      });      return chunk;    });  }  /// Authenticates and returns an authorized client  Future<AuthClient> _getAuthClient() async {    final tokenEndpoint = Uri.parse('https://oauth2.googleapis.com/token');    final response = await http.post(tokenEndpoint, body: {'client_id': clientId,'client_secret': clientSecret,'refresh_token': refreshToken,'grant_type': 'refresh_token',    });    if (response.statusCode != 200) {      throw Exception('Failed to refresh token: ${response.body}');    }    final Map<String, dynamic> json = jsonDecode(response.body);    final credentials = AccessCredentials(      AccessToken('Bearer',        json['access_token'],        DateTime.now().add(Duration(seconds: json['expires_in'])).toUtc(),      ),      null,      scopes,    );    return authenticatedClient(http.Client(), credentials);  }  /// Displays a snackbar with a message  void _showSnackbar(String message) {    ScaffoldMessenger.of(context)        .showSnackBar(SnackBar(content: Text(message)));  }  @override  Widget build(BuildContext context) {    return Stack(      children: [        if (isUploading)          Container(            color: Colors.black.withOpacity(0.5),            child: Center(              child: Column(                mainAxisSize: MainAxisSize.min,                children: [                  //CircularProgressIndicator(value: uploadProgress),                  //SizedBox(height: 16),                  Text('Uploading... ${(uploadProgress * 100).toStringAsFixed(2)}%',                    style: TextStyle(color: Colors.white),                  ),                ],              ),            ),          ),        if (!isUploading)          SizedBox(            width: widget.width,            height: widget.height,            child: ElevatedButton(              onPressed: uploadVideo,              child: const Text('Upload Video'),            ),          ),      ],    );  }}

NOTE

also progress text are not working as excepted ..it shows 0% then 100% after upload is almost done


Viewing all articles
Browse latest Browse all 3722

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>