Gå til innhold

Streaming av video [ffmpeg og qt/c++]


Anbefalte innlegg

Hei!

 

Skriver for øyeblikket en klient-server løsning for streaming av media til telefonen min.

 

Serveren bruker ffmpeg for å gjøre om videoen og lyd til xvid/mp3 og splitter opp videoen i 10-sekunders videoer. Serveren sender så del for del til klienten, som spiller av filene etter hverandre i riktig rekkefølge.

 

Dette fungerer dessverre ikke så godt. Selv om du ikke kan "se" når klienten spiller av neste klipp, så kan du høre at lyden hakker, noe som er kjedelig når det skjer hvert tiende sekund...

 

Har noen forslag på bedre måte å gjøre dette?

Lenke til kommentar
Videoannonse
Annonse

seff kan du det!

du kan jo gjøre den om til det formatet du vil ha på serveren og streame (hele) resultatet til telefonen.

 

å lese/skrive til Nettverk er omtrent det samme som å lese/skrive til en fil, når alt kommer til alt.

 

det eneste du må gjøre på telefon clienten din da, er å lese fra nettverket og ha en passende buffer for å kompansere for tregt/utilgjenglig nettverk.

Lenke til kommentar

Men kan jeg gjøre om formatet samtidig som jeg streamer? Og kan jeg gjøre det ved ett eksternt kall til ffmpeg? Har ikke funnet svar på det noe sted... Skal nevnes at løsningen jeg har nå nesten fungerer, det er bare detta med lyden...

 

jeg har ikke brukt ffmpeg. Da må du nesten sjekke hvilken api kall du har.

Det er ingenting som forhindrer deg å kunne konvertere noe mens du streamer. vanligvis vil dette kun være en funksjon:

ie

char * orginaldata = ....;

char * konvertert;

 

konvertert = encode(orginaldata);

sendToClient(konvertert);

 

Men du konverterer vel allerede i dag til 10 mbs filer, så ser ikke helt hva problemet blir om du konverterer til èn stor?

Lenke til kommentar

Har ikke api kall, kaller eksternt program.

 

Selve konverteringsprossesen er ikke ett problem, men det er ikke alle format man kan se på samtidig som de konverteres (og se ferdig filmen på denne måten), så jeg ser ikke hvordan filmen så skal spilles av før den er ferdig nedlastet...

Lenke til kommentar

Kaller du på et eksternt program kan du bruke pipes, fylle pipen med data, ta i mot data, send i en kontinuerlig strøm. (Antar at du kaller på programmene direkte fra koden din.) Dessverre takler bare popen() enveiskjøring. Hvis du sitter i et POSIX-basert OS kan du bruke

 

socketpair()/fork() klassikeren.

 

Om ikke formatet tillater streaming er det et crap format (hvilke er det snakk om?). (Transkoding?)

 

Bør ikke være verre enn dette:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/wait.h>

int main(void)
{
  int fd[2];

  // Parent får fd[0], child får fd[1]
  if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0)
  {
     perror("socketpair");
     exit(1);
  }

  // Vi er i child. Reroute stdout/stdin til fd[1]
  if (fork() == 0)
  {
     close(0);
     dup(fd[1]);
     close(1);
     dup(fd[1]);

     if (execlp("sed", "sed", "s|OMG|ZOMG|", NULL) < 0)
     {
        char tmp[] = "Halp :v Couldn't start process.";
        write(1, tmp, sizeof(tmp));
     }
     exit(1);
  }
  // Vi er i parent. Ta i mot data fra annen prosess.
  else
  {
     char tmp[] = "OMG";
     // Send data til annen prosess via fd[0]. Prosessen vil kunne lese fra fd[1] via stdin.
     if (write(fd[0], tmp, sizeof(tmp)) < (int)sizeof(tmp))
     {
        perror("write");
        exit(1);
     }
     // Shutter ned write-delen av fd[0]. stdin/fd[1] vil da få hangup hvis den prøver å lese mer, som avslutter sed.
     shutdown(fd[0], SHUT_WR);

     char buffer[2048] = {0};
     // Mottar dataene som prosessen sendte fra stdout, via fd[1] til fd[0].
     if (read(fd[0], buffer, sizeof(buffer) - 1) <= 0)
     {
        perror("read");
        exit(1);
     }

     puts(buffer);
     int status;
     wait(&status); // wait()-er på en zombie-prosess. :3
     printf("Process exited with status: %d\n", (int)WEXITSTATUS(status));
  }

  return 0;
}

 

Istedenfor sed, ffmpeg. Og send() istedenfor puts(). :)

Endret av TheMaister
Lenke til kommentar

Okay... Ser ut til at Qt er litt kresen på hva den tilater "Streaming" fra, så som en workaround har jeg laget min egen lille http server, slik at klient-programmet mitt tror den streamer fra en vilkårlig webside...

 

Problemet er at jeg ikke helt vet hva jeg skal svare på forespørselen... Søkt rundt på google men finner ingen konkrete svar, og er tydeligvis ikke bare å sende avgårde en ByteArray heller...

 

Noen som vet hva Apache eller lignende http servere svarer på en forespørsel som dette?

 

"GET /test.avi HTTP/1.1
Host: 127.0.0.1:8080
Accept: */*
User-Agent: QuickTime/7.6.6 (qtver=7.6.6;cpu=IA32;os=Mac 10.6.4)
Connection: close

" 

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...