2

我想创建一个颤振网站,其中包含 twitch 和 youtube 视频的集合。我尝试使用 video_player 插件,但为此我可以使用 youtube_player 插件,或者我必须使用 API 将所有链接转换为其源文件。但我无法制作嵌入抽搐视频的内容。任何事物。与 youtube 相同的页面会很完美,但是单独的 twitch 播放器也会很好。也许 Twitch API 可以提供帮助,但我不知道如何使用它,也无法理解它。以下是我发现的可能会用到的插件\

1> Video_Player
2> Youtube_Player_plugin
请帮忙

编辑
这是我用来用 ext_video_player 制作 youtube 视频的代码,因为它可以在网络上运行。

class videoBox extends StatefulWidget {
  String Video;
  videoBox(this.Video);
  @override
  _videoBoxState createState() => _videoBoxState(Video);
}

class _videoBoxState extends State<videoBox> {
  String Video;
  bool error = false;
  _videoBoxState(this.Video);
  VideoPlayerController _controller;
  @override
  void dispose(){
    super.dispose();
    _controller.dispose();
  }
  @override
  void initState(){
    super.initState();
      _controller = VideoPlayerController.network(
        Video,
      );

      _controller.initialize().then((value) {
        setState(() {
          print("Initialized");
        });
      });
      _controller.addListener(() {
        if (_controller.value.hasError) {
          print(_controller.value.errorDescription);
          setState(() {
            error = true;
            print(Video);
          });
        }
    });
        }
  @override
  Widget build(BuildContext context) {
    return error?Container(
      decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.all(Radius.circular(15))
      ),
      child: Image(fit:BoxFit.cover,image:NetworkImage("https://hiapseng-thailand.com/wp-content/themes/skywalker/facilities/video-placeholder.jpg"))
    ):GestureDetector(
      onTap:(){
        _controller.value.isPlaying?
        _controller.pause()
            :_controller.play();
      },
      child: Container(
        decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.all(Radius.circular(15))
        ),
        child:  VideoPlayer(_controller,),
    )
    );
  }
}

编辑
我想出了一种使用 iFrame 制作视频的新方法。使用它我可以添加抽搐流,但我只想要视频,而不是聊天和其他东西的全部内容。怎么做?这是我现在使用的coe

class videoBox extends StatefulWidget {
  String Video;
  videoBox(this.Video);
  @override
  _videoBoxState createState() => _videoBoxState(Video);
}

class _videoBoxState extends State<videoBox> {
  String Video;
  IFrameElement iFrame = IFrameElement();
  _videoBoxState(this.Video);

  @override
  Widget build(BuildContext context) {
    iFrame.width = (MediaQuery.of(context).size.width*0.32).toString();
    iFrame.height = (MediaQuery.of(context).size.width*0.27).toString();
    iFrame.src = "https://www.youtube.com/embed/"+Video;
    iFrame.allowFullscreen =true;
    // ignore: undefined_prefixed_name
    ui.platformViewRegistry.registerViewFactory(
      'i'+Video,
          (int viewId) =>iFrame,
    );
    return Container(
        height:MediaQuery.of(context).size.height *0.27,
        width:MediaQuery.of(context).size.width *0.32,
        decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.all(Radius.circular(15))
        ),
        child: HtmlElementView(
            key:UniqueKey(),
            viewType:'i'+Video
        ),
    ) ;
  }
}
4

2 回答 2

0

我们尝试在 Flutter 网络平台上播放视频,但只有这个东西对我有用。要使用文档中的嵌入脚本和 HTML:

所以添加这个库或任何其他可能适用的库htmlwebviewx: ^0.1.0

然后粘贴 HTML sritp:

WebViewX(
        initialContent:
            """<script src= "https://player.twitch.tv/js/embed/v1.js"></script>
                  <div id="${345}"></div>
                  <script type="text/javascript">
                  var options = {
                      width: "${300}",
                      height: "${300}",
                      channel: "icebergdoto",
                      parent: ["your.app","your.ext"]
                    };
                    var player = new Twitch.Player("345", options);
                    player.setVolume(0.5);
                  </script>""",
        initialSourceType: SourceType.HTML,
        onWebViewCreated: (controller) {});

在这种情况下,您仍然可以使用一些变量,例如高度和宽度

于 2021-06-17T06:38:40.953 回答
0

Update

Making HTTP requests to the Twitch API is fairly easy. You have to register your application on the Twitch dev console. This will grant you access to both a client id and a client secret. Refer to the documentation for a detailed guide.

With those two, you can make a request which generates an app access token. Getting a video id is simply hitting a different endpoint. It requires a game id and/or user id as per the documentation

URL

GET https://api.twitch.tv/helix/videos

Required Query Parameters

Each request must specify one or more video ids, one user_id, or one game_id.

In the example below I generated an app access token, using my own client id and secret. Got a game id from another endpoint and finally retrieved a video id from the game id.

class TwitchAPIService {
  // Making a singleton pattern ensures only one instance of a class is ever created

  TwitchAPIService._internal();

  static final TwitchAPIService _twitchAPIService = TwitchAPIService._internal();

  static TwitchAPIService get twitchAPIService => _twitchAPIService;

  String twitchClientID, twitchClientSecret; // This are to be gotten from the Twitch developer console

  Future<String> fetchAppAccessToken() async {
    final baseUrl = 'id.twitch.tv';
    Map<String, String> parameters = {
      'client_id': twitchClientID,
      'client_secret': twitchClientSecret,
      'grant_type': 'client_credentials',
    };

    Map<String, String> headers = {
      'Accept': 'application/json',
    };

    Uri uri = Uri.https(baseUrl, '/oauth2/token', parameters);

    var token;
    try {
      token = await http.post(uri, headers: headers);
      if (token.statusCode == 200) {
        // Make secure requests with the token.
        return token.body;
      }
      return json.decode(token.body)['message'];
    } catch (e) {
      return json.decode(token.body)['message'];
    }
  }

  // This gets the game Id of any given game under Twitch's game library
  Future<String> fetchGameId(String token) async {
    final baseUrl = 'api.twitch.tv';
    Map<String, String> parameters = {
      'name': 'fortnite',
    };
    Map<String, String> headers = {
      'Accept': 'application/json',
      'Authorization': 'Bearer $token',
      'Client-id': twitchClientID,
    };

    Uri uri = Uri.https(baseUrl, '/helix/games', parameters);

    try {
      var gameId = await http.get(uri, headers: headers);
      return gameId.body;
    } catch (e) {
      return e.toString();
    }
  }
  // This retrieves videoId(s) under a particular gameId
  Future<dynamic> fetchVideoId(String gameId) async {
    final baseUrl = 'api.twitch.tv';
    Map<String, String> parameters = {
      'game_id': gameId,
    };
    Map<String, String> headers = {
      'Accept': 'application/json',
      'Authorization': 'Bearer 4aq6y8pqjyw7cc9x4o8el7zha1ua8u',
      'Client-id': twitchClientID,
    };
    Uri uri = Uri.https(baseUrl, '/helix/videos', parameters);
    try {
      var videoId = await http.get(uri, headers: headers);
      return videoId.body;
    } catch (e) {
      return e.toString();
    }
  }
}

A Hacked Solution

The Twitch API offers various services, such as getting streams, channel details and so much more. I'll cut right to the chase and assume you have already set up your Twitch developer account here.

Note: In regards to your question, you don't have to have an active developer account. Although if you want to use other services like the ones mentioned above, you would need a form of Authentication hence a Twitch developer account.


Prerequisite

  1. A WebView package preferably Flutter Inappwebview.
  2. A Twitch channel name or video ID. This can be hardcoded or gotten dynamically using the Twitch API. The idle way to getting it should be the latter. For the sake of this answer, I have a random video ID below.
  3. A deployed website bundled with a ssl certificate ( Optional ).

Please point 3 is strongly required. Usually, most developers would just directly save the html content locally in a html file or even directly write it out in dart files.

According to this thread, this will not work. The embedded Twitch player will only work over a localhost and/or a website coupled with a ssl certificate. Some hosting services automatically bundle any deployed website with a ssl certificate. I am very sure Firebase Hosting does this. You can skip this part since, testing locally is supported.

Other things to keep in mind

Local development

Use “localhost” or any IP address in the “127.0.0.1/8” range as the parent value to use either HTTP or HTTPS in local development. Any port can be used, though this does not need to be specified anywhere (80, 3000, 8100, etc) Local development over other IP ranges (e.g. 192.1.1.1) must adhere to the HTTPS requirement, though a valid certificate is not required


Now unto the codebase.

  • Create an index.html file which would contain the Official Iframe Player.

     <!DOCTYPE html>
     <html>
    
     <head>
         <style>
             html,
             body {
                 margin: 0;
                 padding: 0;
                 background-color: #000000;
                 overflow: hidden;
                 position: fixed;
                 height: 100%;
                 width: 100%;
             }
         </style>
         <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'>
     </head>
    
     <body>
         <div id="player"></div>
         <script src="https://player.twitch.tv/js/embed/v1.js"></script>
         <div id="<player div ID>"></div>
         <script type="text/javascript">
             var options = {
                 width: window.innerWidth,
                 height: window.innerHeight,
                 video: "335180634",
                 // This should be used locally.
                 // If deployed, i.e not local then the parent should be the url of your website.
                 // For example if the full url of our deployed website is https://www.flutterproject.com then the parent would be
                 // parent: ["flutterproject.com"]
                 parent: ["localhost"]
             };
             var player = new Twitch.Player("<player div ID>", options);
             player.setVolume(0.5);
         </script>
     </body>
    
     </html>
    

The main thing to focus on is the script block. It contains the Interactive iframe player. It also accepts an options object which can be customised. Much more parameters can be found here. You can simply move that code snippet into an editor an open it on a live server, to make sure it works.

  • The Dart Side.

Basically, we use some sort of WebView to open up our deployed website that contains the html content mention in point 1. We also have to give constraints to the WebView in order to place it along other widgets. A simple aspect Ratio of 16:9 should be sufficient.

Enabling allowsInlineMediaPlayback: true would make sure that the video players in the correct aspect ratio. Setting it to false, will have an effect of causing the video to dive into fullscreen on IOS.

main(List<String> args) {
  runApp(
    MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.black,
        appBar: AppBar(
          title: Text('Twtich Embed'),
        ),
        body: AspectRatio(
          aspectRatio: 16 / 9,
          child: InAppWebView(
            key: UniqueKey(),
            initialUrl: 'flutterproject.com',
            initialOptions: InAppWebViewGroupOptions(
              ios: IOSInAppWebViewOptions(allowsInlineMediaPlayback: true),
              crossPlatform: InAppWebViewOptions(
                mediaPlaybackRequiresUserGesture: false,
                transparentBackground: true,
              ),
            ),
          ),
        ),
      ),
    ),
  );
}

Notes

Downsides

  • This solution will push traffic to your own managed website.
  • It might be relatively slow depending on how you optimise your deployed website.

Upside(s)

  • It is the only way Twitch supports mobile embeds, as they do not have a native sdk.
于 2020-12-16T14:28:53.357 回答