AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 78908102
Accepted
Jeff
Jeff
Asked: 2024-08-24 12:06:20 +0800 CST2024-08-24 12:06:20 +0800 CST 2024-08-24 12:06:20 +0800 CST

Como posso criar um objeto Media em javafx a partir de uma matriz de bytes?

  • 772

Estou tentando reproduzir mídia em javafx usando MediaView, MediaPlayer e Media. A classe Media parece aceitar apenas uma fonte de URL para criar Media (que é usada para passar para o MediaPlayer). Gostaria de passar uma matriz de bytes em cache para criar o objeto Media. Isso é compatível?

Consegui reproduzir mídia usando um URL e um arquivo, mas não uma matriz de bytes.

javafx
  • 2 2 respostas
  • 36 Views

2 respostas

  • Voted
  1. Best Answer
    jewelsea
    2024-08-24T13:16:02+08:002024-08-24T13:16:02+08:00

    Do documento de mídia “Apenas URIs HTTP, HTTPS, FILE e JAR são suportados.”. Então você precisa servir seus bytes de um provedor em um desses protocolos.

    Você pode executar um servidor http incorporado e servir os bytes dele usando o protocolo http.

    Ou você pode usar um sistema de arquivos na memória, servindo os bytes usando os protocolos file ou jar.

    Exemplo de servidor http incorporado servindo conteúdo de bytes na memória .

    O exemplo serve tipos MIME de imagem, mas servir outros tipos de conteúdo para mídia funcionaria desde que o fluxo de entrada estivesse correto (por exemplo, representa dados mp3 ou mp4 codificados corretamente).

    • 1
  2. Slaw
    2024-08-25T13:23:46+08:002024-08-25T13:23:46+08:00

    A opção mais simples seria gravar os bytes em um arquivo e depois passar um fileURI para o Mediaconstrutor.

    public Media toMediaFile(byte[] bytes, String extension) throws IOException {
      Objects.requireNonNull(bytes);
      if (extension.isBlank())
        throw new IllegalArgumentException("blank extension");
      var file = Files.createTempFile("jfxmedia", "." + extension);
      Files.write(file, bytes, StandardOpenOption.WRITE);
      return new Media(file.toUri().toString());
    }
    

    No entanto, se você quiser manter os bytes da mídia na memória, acho que a solução mais fácil seria uma das sugestões da resposta do Jewelsea : Crie um servidor incorporado para servir a mídia por HTTP. Você pode usar o jdk.httpservermódulo para isso. Um exemplo usando esse módulo é dado nesta outra resposta do Jewelsea (vinculada na resposta a esta pergunta). Mas aqui está outro exemplo mais específico para o seu caso de uso.

    Código do servidor

    Observe que este servidor de exemplo não está implementado para lidar com o Rangecabeçalho HTTP. Acredito que a implementação de mídia JavaFX usará esse cabeçalho, pelo menos em alguns casos. Você pode querer implementar a funcionalidade no servidor.

    Além disso, pode ser mais fácil encontrar uma biblioteca de servidor HTTP com mais recursos e adicioná-la ao seu projeto como uma dependência, em vez de usar o jdk.httpservermódulo. Embora o último deva ser suficiente para um servidor simples e básico que existe apenas para servir byte[]matrizes por HTTP no host local.

    InMemoryMedia.java

    package com.example;
    
    public record InMemoryMedia(byte[] bytes, String contentType) {
       
      public int contentLength() {
        return bytes.length;
      }
    }
    

    InMemoryMediaServer.java

    package com.example;
    
    import com.sun.net.httpserver.HttpContext;
    import com.sun.net.httpserver.HttpServer;
    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.net.URI;
    import java.net.URISyntaxException;
    import java.util.Objects;
    import java.util.concurrent.Executors;
    import java.util.concurrent.atomic.AtomicBoolean;
    
    public class InMemoryMediaServer implements AutoCloseable {
    
      private final HttpServer httpServer;
    
      public InMemoryMediaServer(int port) throws IOException {
        var address = new InetSocketAddress(InetAddress.getLoopbackAddress(), port);
        httpServer = HttpServer.create(address, 1);
        httpServer.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
        httpServer.start();
      }
    
      public RegistrationKey registerMedia(String path, InMemoryMedia media) {
        Objects.requireNonNull(path);
        Objects.requireNonNull(media);
    
        var context = httpServer.createContext(path, new InMemoryMediaHandler(media));
        return new RegistrationKey(context);
      }
    
      @Override
      public void close() {
        httpServer.stop(0);
      }
    
      public class RegistrationKey {
    
        private final AtomicBoolean unregistered = new AtomicBoolean();
        private final HttpContext context;
    
        RegistrationKey(HttpContext context) {
          this.context = context;
        }
    
        public URI uri() {
          var addr = httpServer.getAddress();
    
          var scheme = "http";
          var host = addr.getAddress().getHostAddress();
          int port = addr.getPort();
          var path = path();
    
          try {
            return new URI(scheme, null, host, port, path, null, null);
          } catch (URISyntaxException ex) {
            throw new IllegalArgumentException(ex);
          }
        }
    
        public String path() {
          return context.getPath();
        }
    
        public void unregister() {
          if (unregistered.compareAndSet(false, true)) {
            httpServer.removeContext(context);
          }
        }
      }
    }
    

    InMemoryMediaHandler.java

    package com.example;
    
    import com.sun.net.httpserver.Headers;
    import com.sun.net.httpserver.HttpExchange;
    import com.sun.net.httpserver.HttpHandler;
    import java.io.IOException;
    
    final class InMemoryMediaHandler implements HttpHandler {
    
      private final InMemoryMedia media;
    
      InMemoryMediaHandler(InMemoryMedia media) {
        this.media = media;
      }
    
      @Override
      public void handle(HttpExchange exchange) throws IOException {
        switch (exchange.getRequestMethod()) {
          case "HEAD" -> {
            setResponseHeaders(exchange.getResponseHeaders());
            exchange.sendResponseHeaders(200, -1);
          }
          case "GET" -> {
            setResponseHeaders(exchange.getResponseHeaders());
            exchange.sendResponseHeaders(200, media.contentLength());
            try (var out = exchange.getResponseBody()) {
              out.write(media.bytes());
            }
          }
          default -> exchange.sendResponseHeaders(405, -1);
        }
      }
    
      private void setResponseHeaders(Headers headers) {
        headers.set("Accept-Ranges", "none");
        headers.set("Content-Type", media.contentType());
        headers.set("Content-Length", Integer.toString(media.contentLength()));
      }
    }
    

    Código do aplicativo

    Algum código mostrando como usar a InMemoryMediaServerclasse.

    Principal.java

    package com.example;
    
    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.scene.media.Media;
    import javafx.scene.media.MediaPlayer;
    import javafx.scene.media.MediaView;
    import javafx.stage.Stage;
    
    public class Main extends Application {
    
      private InMemoryMediaServer server;
      private String mediaUri;
    
      @Override
      public void init() throws Exception {
        server = new InMemoryMediaServer(8888);
    
        var key = server.registerMedia("/test", getInMemoryMedia());
        mediaUri = key.uri().toString();
      }
    
      private InMemoryMedia getInMemoryMedia() {
        throw new UnsupportedOperationException("not implemented"); // TODO: Implement
      }
    
      @Override
      public void start(Stage primaryStage) {
        var media = new Media(mediaUri);
        media.setOnError(() -> media.getError().printStackTrace());
    
        var player = new MediaPlayer(media);
        player.setAutoPlay(true);
    
        primaryStage.setScene(new Scene(new StackPane(new MediaView(player))));
        primaryStage.show();
      }
    
      @Override
      public void stop() {
        server.close();
      }
    }
    
    • 0

relate perguntas

  • Node.snapshot() não vê alterações no nó no JavaFX

  • Cena JavaFX minWidth e minHeight não funcionam

  • Como faço para que o Togglebutton funcione corretamente dentro da coluna tableView?

  • Tendo problemas com Javafx ListView

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve