sarbagyastha / youtube_player_flutter

A Flutter plugin for inline playback or streaming of YouTube videos using the official iFrame Player API.
https://youtube.sarbagyastha.com.np
BSD 3-Clause "New" or "Revised" License
713 stars 829 forks source link

[BUG] If videoId contains dashes (-), ID is trimmed and video fails to load. #981

Open NorteX-dev opened 3 months ago

NorteX-dev commented 3 months ago

Is there an existing issue for this?

Package

youtube_player_iframe (Default)

What happened?

Let's assume the youtube video ID contains dash symbols, the video fails to load, since the ID is trimmed to the strnig preceding the dash.

Take this ID for example: Jl1-bmN1b8o (this is a correct youtube id). This contains a dash as the fourth char. A video player is constructed (minimal repro below) with said ID. The video fails to load, the app shows "An error occured" and you can see, how the wrong ID is fetched and printed: I/chromium(31976): [INFO:CONSOLE(123)] "Uncaught ReferenceError: YoutubeJl1 is not defined", source: https://www.youtube.com/ (123)

As you can see, it's trying to load YoutubeJl1, which is where the dash was met.

What is the expected behaviour?

The ID is not trimmed. Video is played as should.

How to reproduce?

Use this minimal reproduction:

main.dart:

import 'package:flutter/material.dart';
import 'package:testapp/widgets/video_player.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return const Column(
                     // Widget is initialized
      children: [VideoPlayer(videoId: "Jl1-bmN1b8o")],
    );
  }
}

widgets/video_player.dart:

import 'package:flutter/material.dart';
import 'package:youtube_player_iframe/youtube_player_iframe.dart';

class VideoPlayer extends StatefulWidget {
  final String videoId;
  const VideoPlayer({super.key, required this.videoId});

  @override
  State<VideoPlayer> createState() => _VideoPlayerState();
}

class _VideoPlayerState extends State<VideoPlayer> {
  bool isPlayerOn = true;
  late final YoutubePlayerController controller;

  @override
  void initState() {
    super.initState();

    print(widget.videoId); // -> Jl1-bmN1b8o
    controller = YoutubePlayerController.fromVideoId(
      videoId: widget.videoId,
    );
  }

  @override
  void didUpdateWidget(covariant VideoPlayer oldWidget) {
    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    if (!isPlayerOn) {
      controller.pauseVideo();
    }

    return Column(
      children: [
        Visibility(
          visible: isPlayerOn,
          maintainState: true,
          maintainAnimation: true,
          child: YoutubePlayer(
            controller: controller,
            aspectRatio: 16 / 9,
          ),
        ),
      ],
    );
  }
}

The above code contains a VideoPlayer widget and a home page.

Screenshot_20240821-142534

pubspec.yaml

youtube_player_iframe: ^5.1.5
hnvn commented 2 months ago

+1

hnvn commented 2 months ago

I have to downgrade the plugin to v5.1.3 to fix this issue

ponlakrit-k commented 1 month ago

Same issue here.

gustysetyono commented 1 month ago

same issue

SLT-DJH commented 3 weeks ago

I used cueVideoByUrl() function to play video which has dash inside video id.

before

_controller = YoutubePlayerController.fromVideoId( videoId: widget.data.videoUrl!, startSeconds: widget.data.startSeconds, endSeconds: widget.data.endSeconds, params: const YoutubePlayerParams( mute: false, loop: false, enableCaption: true, ), );

after

_controller = YoutubePlayerController( params: const YoutubePlayerParams( mute: false, loop: false, enableCaption: true, ));

_controller.cueVideoByUrl( mediaContentUrl: "http://www.youtube.com/v/${widget.data.videoUrl!}?version=5", startSeconds: widget.data.startSeconds, endSeconds: widget.data.endSeconds);

Anupdas commented 1 week ago

I used cueVideoByUrl() function to play video which has dash inside video id.

before

_controller = YoutubePlayerController.fromVideoId( videoId: widget.data.videoUrl!, startSeconds: widget.data.startSeconds, endSeconds: widget.data.endSeconds, params: const YoutubePlayerParams( mute: false, loop: false, enableCaption: true, ), );

after

_controller = YoutubePlayerController( params: const YoutubePlayerParams( mute: false, loop: false, enableCaption: true, ));

_controller.cueVideoByUrl( mediaContentUrl: "http://www.youtube.com/v/${widget.data.videoUrl!}?version=5", startSeconds: widget.data.startSeconds, endSeconds: widget.data.endSeconds);

This helped resolve the issue. Thanks for sharing.

Yom3n commented 1 week ago

Any update on this?