Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Youtube Altyazı Downloader (TimedText)
#1
@pro_imaj ile özel mesaj ile konu hakkında görüşüyorduk. 
Örnek bir taslak proje hazırladım, buradan paylaşalım kararını beraber verdik.

Forma TEdit, TMemo, TListbox birer tane bırakın.

rnpr46sr9gb6njyfy7es.png

 



Proje EXE Klasörünüzde OpenSSL DLL'lerini koymayı unutmayın. (libeay32.dll ve ssleay32.dll)
 
Uses
  JSON,
 System.Generics.Collections,
 System.IOUtils,
 IdSSLOpenSSL, IdSSLOpenSSLHeaders,
 IdHTTP, IdIOHandler;

type
 TLinkDetails = Record
   baseUrl,
   name,
   vssId,
   languageCode,
   isTranslatable : string;
 end;
 PLinkDetails = ^TLinkDetails;

function  aHttpGet( aUrl: String ): String;
var
 aIdHttp     : TIdHttp;
 aIOHandler  : TIdSSLIOHandlerSocketOpenSSL;
begin
 {$IF defined(ANDROID)}
   IdOpenSSLSetLibPath(TPath.GetDocumentsPath);
 {$ENDIF}
 aIdHttp     := TIdHTTP.Create(nil);
 aIOHandler  := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
 try
   aIOHandler.PassThrough        := True;
   aIOHandler.SSLOptions.Method  := TIdSSLVersion.sslvTLSv1_2;
   with aIdHttp do
   begin
     IOHandler         := aIOHandler;
     HandleRedirects   := True;
     Request.Accept    := 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
     Request.CharSet   := 'ISO-8859-1,utf-8;q=0.7,*;q=0.7';
     Request.UserAgent := 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'; // 'Dalvik/2.1.0 (Linux; U; Android 8.0.0; SM-N950F Build/R16NW)';
     Result            :=  Get( aUrl );
   end;
 finally
   FreeAndNil( aIdHttp );
   FreeAndNil( aIOHandler );
 end;
end;

procedure YoutubeSubtitleLinks( VideoID: String; aList: TStrings );
Const
 VideoLinkFmt = 'https://www.youtube.com/watch?v=%s';
var
 aResponse   : String;
 aSearch     : String;
 aJSONData   : TJSONValue;
 aJSONValue  : TJSONValue;
 aJSONArray  : TJSONArray;
 aCaption    : TJSONValue;
 i : Integer;
 aLinkDetails : PLinkDetails;
begin
 if aList.Count > 0 then begin
   for i := 0 to pred(aList.Count) do
     Dispose( PLinkDetails( aList.Objects[i] ) );
   aList.Clear;
 end;

 aResponse :=  aHttpGet(  Format( VideoLinkFmt, [ VideoID ] ) );

 aSearch   := 'window["ytInitialPlayerResponse"] = ';
 System.Delete( aResponse, 1, Pos(aSearch, aResponse) + Length(aSearch)-1 );

 aResponse := Trim( Copy( aResponse, 1, Pos( #10'    ', aResponse )-1 ) );
 aResponse := Copy( aResponse, 1, Length(aResponse)-1 ); // delete last (;) for validate JSON

// -------------------------------------------------------------------------- //
// JSON Parse section
// -------------------------------------------------------------------------- //
 aJSONData := JSON.TJSONObject.ParseJSONValue( TEncoding.ASCII.GetBytes( Trim(aResponse) ), 0);
 try
   if aJSONData <> nil then
   begin
     if aJSONData.FindValue( 'captions' ) <> nil then
     begin
       aJSONValue := aJSONData.GetValue<TJSONObject>('captions');
       if aJSONValue.FindValue('playerCaptionsTracklistRenderer') <> nil then
       begin
         aJSONValue := aJSONValue.GetValue<TJSONObject>('playerCaptionsTracklistRenderer');
         if aJSONValue.FindValue('captionTracks') <> nil then
         begin
           aJSONArray := aJSONValue.GetValue<TJSONArray>('captionTracks');
           i := 0;
           while ( i < aJSONArray.Count ) do
           begin
             aCaption := TJSONObject( aJSONArray.Items[i] );
             new( aLinkDetails );

             if aCaption.FindValue( 'baseUrl'         ) <> nil then
               aLinkDetails.baseUrl        := ((aCaption as TJSONObject).Get('baseUrl'       ).JsonValue as TJSONString).Value;

             if  ( aCaption.FindValue( 'name' ) <> nil )
             AND ( TJSONObject(aCaption.FindValue('name')).FindValue('simpleText') <> nil ) then
               aLinkDetails.name := (( TJSONObject(aCaption.FindValue('name')).Get('simpleText') ).JsonValue as TJSONString).Value;

             if aCaption.FindValue( 'vssId'           ) <> nil then
               aLinkDetails.vssId          := ((aCaption as TJSONObject).Get('vssId'         ).JsonValue as TJSONString).Value;

             if aCaption.FindValue( 'languageCode'    ) <> nil then
               aLinkDetails.languageCode   := ((aCaption as TJSONObject).Get('languageCode'  ).JsonValue as TJSONString).Value;

             if aCaption.FindValue( 'isTranslatable'  ) <> nil then
               aLinkDetails.isTranslatable := ((aCaption as TJSONObject).Get('isTranslatable').JsonValue as TJSONBool).ToString;

             aList.AddObject( aLinkDetails.name, TObject( aLinkDetails ) );
             inc(i);
           end;
         end;
       end;
     end;
   end;
 finally
   aJSONData.Free;
 end;
end;

procedure TimedTextDownload( aUrl: String; aList: TStrings );
var
 aResponse   : String;
begin
 aResponse   := aHttpGet( aUrl );
 aResponse   := StringReplace( aResponse, '</text>', '</text>'#10, [rfReplaceAll] );
 aResponse   := StringReplace( aResponse, '&amp;#39;', '''', [rfReplaceAll] );
 aList.Text  := aResponse;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 aVideoLink : String;
begin
//  Youtube Video Link Sample
//  https://www.youtube.com/watch?v=Zh3Yz3PiXZw&t=39s

//Parse Videolink from URL
 aVideoLink := Edit1.Text;
 if Pos('v=',  aVideoLink  ) > 0 then System.Delete      ( aVideoLink, 1, Pos('v=',  aVideoLink) + 1 );
 if Pos('&',   aVideoLink  ) > 0 then aVideoLink := Copy ( aVideoLink, 1, Pos('&',   aVideoLink) - 1 );

 YoutubeSubtitleLinks( aVideoLink, ListBox1.Items );
end;

procedure TForm1.Button2Click(Sender: TObject);
var
 aLinkDetail : PLinkDetails;
 aUrl        : String;
begin
 if ListBox1.ItemIndex < 0 then Exit;

 aLinkDetail := PLinkDetails( ListBox1.Items.Objects[ListBox1.ItemIndex] );
 aUrl        := aLinkDetail.baseUrl;
 TimedTextDownload( aUrl, Memo1.Lines );
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 ReportMemoryLeaksOnShutdown := True;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
i : Integer;
begin
 // for avoiding memory leak, free up item object pointer allocations before all.
 if ListBox1.Items.Count > 0 then
 begin
   for i := 0 to pred(ListBox1.Items.Count) do
     Dispose( PLinkDetails(ListBox1.Items.Objects[i]) );

   ListBox1.Items.Clear;
 end;
end;
Saygılarımla
Muharrem ARMAN

guplouajuixjzfm15eqb.gif
Cevapla
#2
Elinize sağlık. Paylaşım için teşekkürler.
Cevapla
#3
Emeğine sağlık @mrmarman
There's no place like 127.0.0.1
WWW
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Youtube atakan 5 4.656 28-06-2020, Saat: 17:23
Son Yorum: mrmarman
  YouTube Api VCL & FMX AliZairov 6 8.470 02-03-2018, Saat: 17:17
Son Yorum: AliZairov
  Youtube Component barisatalay 2 5.351 28-09-2016, Saat: 11:22
Son Yorum: Fesih ARSLAN



Konuyu Okuyanlar: 1 Ziyaretçi