Σελ. 21 από 21 ΠρώτηΠρώτη ... 1116192021
Εμφάνιση 301-309 από 309
  1. #301
    Εγγραφή
    28-01-2008
    Ηλικία
    53
    Μηνύματα
    2.578
    Downloads
    13
    Uploads
    0
    Τύπος
    VDSL2
    Ταχύτητα
    51200/5120
    ISP
    Vodafone
    Router
    Vodafone H-300s
    Θα έλεγα να μείνει όσο πιο απλό γίνεται τώρα στην αρχή, να το δοκιμάσουν αρκετοί, και μετά θα έρθουν οι ιδέες για βελτίωση :-)

  2. #302
    Εγγραφή
    08-03-2007
    Μηνύματα
    25.648
    Downloads
    26
    Uploads
    0
    ISP
    ΟΤΕ Conn-x
    Να το βαλεις να κατεβαζει τα dash strems γιατι τα hls εχουν προβλημα.
    https://www.adslgr.com/forum/threads...=1#post7631818
    ديميتريس

  3. #303
    Εγγραφή
    05-05-2003
    Περιοχή
    Λάρισα
    Μηνύματα
    9.623
    Downloads
    9
    Uploads
    0
    Τύπος
    VDSL2
    Ταχύτητα
    204800/20480
    ISP
    CosmOTE
    DSLAM
    ΟΤΕ - ΑΚΑΔΗΜΙΑ
    Router
    FRITZ!Box 7590
    Path Level
    Fastpath
    Παράθεση Αρχικό μήνυμα από jim_p Εμφάνιση μηνυμάτων
    Να το βαλεις να κατεβαζει τα dash strems γιατι τα hls εχουν προβλημα.
    https://www.adslgr.com/forum/threads...=1#post7631818
    +1

  4. #304
    Εγγραφή
    04-05-2025
    Μηνύματα
    13
    Downloads
    0
    Uploads
    0
    ISP
    Vodafone
    Έτοιμο το πρόγραμμα. Το αρχείο ARRAY_ERTFLIX πάει πλέον στον φάκελο του χρήστη.
    Όποτε εάν υπάρχει φάκελος home/pi κάντε διαγραφή.
    Δοκιμάστε και εάν έχει κάποιο πρόβλημα εδώ είμαστε. Μονό για οποία επίλυση και προσθήκη θα αργήσει λόγο υποχρεώσεων. Το έχω δοκιμάσει, ελεύθερα μπορείτε να κάνετε οποιαδήποτε προσθήκη
    Κώδικας:
    #!/bin/bash
    
    if [ ! -f /home/${USER}/ARRAY_ERTFLIX ]; then
    cat /dev/null > /home/${USER}/ARRAY_ERTFLIX
    fi
    
    mapfile -t Array_Series_ERTFLIX < /home/${USER}/ARRAY_ERTFLIX
    
    #--------------------------------Εισαγωγή link---------------------------------------------------------
    if [[ -z "$Array_Series_ERTFLIX" ]]; then
    while true; do
    
    #εισαγωγη links απο ertflix
      tmpfile=$(mktemp)
    
      yad --center --form --fixed \
        --field="<span color='#0000FF'>link1</span>:H50" '' \
        --width=550 --height=200 --title="Επιλογή link" \
        --text="<span font='DejaVu Sans Book 10'>Παρακαλώ εισάγετε τους συνδέσμους των βίντεο.\nΒεβαιωθείτε ότι οι σύνδεσμοι είναι έγκυροι και πλήρεις.\nΣτη συνέχεια πατήστε ΟΚ.</span>" \
        --entry-text-maxlen=50 --buttons-layout=center \
        --print-partial --button="gtk-quit:252" --button="gtk-ok:0" \
        --no-escape --window-icon=insert-link --borders=10 --no-icon \
        > "$tmpfile" 2>/dev/null
    
                 response=$?
    
                 if [[ $response -eq 252 ]]; then
                   rm -f "$tmpfile"
                   exit
                 elif [[ $response -eq 0 ]]; then
                   links_temp=$(cat "$tmpfile")
                   rm -f "$tmpfile"
                 fi
    
      links_ertflix="$links_temp"
      links_var=$(echo "$links_ertflix" | sed 's/|//g')
    
      echo "$links_var"
    
    #ελενχος εαν δεν εχει επιλεγη καποιο link
           if [ -z $links_var ]; then
              yad --center --fixed --width=500 --height=100 --image="face-embarrassed" --window-icon=gtk-dialog-warning --title="Warning" --text-align=center --button="gtk-quit:1" --timeout 3 --text="<span font='DejaVu Sans Book 4'>\n</span>\
    <span font='DejaVu Sans Book 4'>\n</span>\
    <span color='#CC2222' font='Sans Bold 12'>
    Δεν έχει επιλεγεί κάποιο link</span>" 2>/dev/null
    
    
                 response=$?
    
                 if [[ $response -eq 252 ]]; then
                   exit 0
                 fi
                   continue
    #τελος ελενχου εαν δεν εχει επιλεγη καποιο link
           fi
    
      IFS='|' read -r -a link_array_ert <<< "$links_ertflix"
    
      declare -a all_mpd_links=()
    
        for link in "${link_array_ert[@]}"; do
           if [[ -n $link ]]; then
             json_output=$(yt-dlp -F "$link" --dump-json 2>/dev/null)
             mpd_links=$(echo echo "$json_output" | grep -oP 'https://[^"]*' | grep '\/index.mpd' \
             | grep -v '_web' | grep -v '_web_' | grep -v '\.m3u8' | grep -v '\.mp4' |grep -v '\.mp4' | grep -v '\/dash\/' | sed 's/"[^"]*web\/index\.mpd"//g')
    
             found_valid_mpd=false
             wrong_mpd=0
    
             while IFS= read -r url; do
               if [[ "$url" =~ \.mpd$ ]]; then
                all_mpd_links+=("$url")
                found_valid_mpd=true
               else
                wrong_mpd=$((wrong_mpd + 1))
               fi
             done <<< "$mpd_links"
    
    #Ελεγχος εαν δεν υπαρχουν .mpd
    
              if [[ "$found_valid_mpd" == "false" ]] && [[ ${#all_mpd_links[@]} -eq 0 ]]; then
              yad --center --fixed --width=500 --height=100 --title="Προβληματικό link" \
              --image="face-sick" --window-icon=gtk-dialog-warning --text-align=center \
              --text="Το link:\n<b>$link</b>\n<span color='#CC2222' font='Sans Bold 12'>Δεν επέστρεψε καμία έγκυρη .mpd URL.</span>" \
              --button="gtk-quit:252" --timeout 4 2>/dev/null
             
                 response=$?
    
                 if [[ $response -eq 252 ]]; then
                   exit 0
                 fi
             
                 save_mpd=0
              fi
    
    #Ελεγχος εαν υπαρχουν .mpd και μια ή περισοτερες url επιστρεφουν λαθος   
                 if [ "$wrong_mpd" -eq 1 ]; then
                  authority="έγκυρη"
                 else
                  authority="έγκυρες"
                 fi
    
              if [[ "$found_valid_mpd" == "true" ]] && [[ "$wrong_mpd" -ge 1 ]]; then
              yad --center --fixed --width=500 --height=100 --text-align=center --title="Μερικές .mpd URLs" \
              --image=face-monkey --window-icon=gtk-dialog-question \
              --text="Το link:\n<b>$link</b>\nΕπιστρέφει ${#all_mpd_links[@]} URLs .mpd\n<span color='#CC2222' font='Sans Bold 12'>Δεν επέστρεψε ${wrong_mpd} ${authority} URLs.</span>
    Να προστεθούν οι υπόλοιπες .mpd URLs;" \
              --button="gtk-quit:252" --button="Όχι:1" --button="Ναι:0" 2>/dev/null
    
                 response=$?
           
                 if [[ $response -eq 252 ]]; then
                  exit 0
                 elif [[ $response -eq 0 ]]; then
                  save_mpd=1
                  #continue
                 elif [[ $response -eq 1 ]]; then
                  save_mpd=1
                 fi
    
              fi
    
    #Ολα τα url ειναι .mpd  
              if [[ "$found_valid_mpd" == "true" ]] && [[ "$wrong_mpd" -eq 0 ]]; then
                 save_mpd=1
              fi
    
    #τελος if [[ -n $link ]]; then
           fi
    #τελοσ     for link in "${link_array_ert[@]}"; do
         done
    
    #Καταργιση των διπλων .mpd και αποθηκευση στο αρχειο ARRAY_ERTFLIX
              if [ "$save_mpd" == 1 ]; then
                 valid_unique_mpd_links=$(printf "%s\n" "${all_mpd_links[@]}" | grep '\.mpd$' )
                 valid_unique_mpd_link=$(echo "$valid_unique_mpd_link" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
                 duplicates=$(printf "%s\n" "${all_mpd_links[@]}" | sort | uniq -c | awk '$1 > 1 { print $2 }')
                 printf "%s\n%s\n" "$duplicates" "$(cat /home/${USER}/ARRAY_ERTFLIX 2>/dev/null)" > /home/${USER}/ARRAY_ERTFLIX
                 sed -i '/^$/d' /home/${USER}/ARRAY_ERTFLIX
              fi
    
              yad --center --fixed --width=500 --height=100 --image=dialog-question --title="Continue insert" --text="<span font='DejaVu Sans Book 4'>\n</span>\
    <span font='DejaVu Sans Book 10'>Θέλεται να συνεχιστεί η προσθήκη link;
    Για προσθήκη πατήστε ΟΚ</span>" --button="gtk-quit:252" --button="gtk-cancel:1" --button="gtk-ok:0" 2>/dev/null
    
                 response=$? 
    
                 if [[ $response -eq 252 ]]; then
                  exit 0  
                 elif [[ $response -eq 0 ]]; then
                  continue
                 elif [ $response -eq 1 ]; then
                  break
                 fi 
    
    
    
    #τελοσ while true; do
    done
    fi
    
    #---------------------------------------Εισαγωγή απο αρεχεο ertflix--------------------------------------------
    current_audio_array=""
    current_video_array=""
    
    y=0
    select=0
    while true; do
    mapfile -t Array_Series_ERTFLIX < /home/${USER}/ARRAY_ERTFLIX
    if [[ "${#Array_Series_ERTFLIX[@]}" -gt 0 ]]; then
    
    
    yad --center --fixed --title="Complete File ARRAY_ERTFLIX" --text="<span font='DejaVu Sans Book 20'>\n</span>\
    <span font='DejaVu Sans Book 12'>Υπάρχουν ${#Array_Series_ERTFLIX[@]} links για κατέβασμα</span>" \
    --window-icon=insert-link --image="insert-link" --text-align=center --button="gtk-quit:252" --width=500 --height=100 --timeout 3 2>/dev/null
    
    
                 response=$?
    
                 if [[ $response -eq 252 ]]; then
                  exit 0
                 fi
    
     for (( l=0; l<${#Array_Series_ERTFLIX[@]}; l++ )); do
      links=$(echo ${Array_Series_ERTFLIX[$l]})
      name=$(echo "$links" | awk -F'/' '{print $(NF-1)}')
    
    #---------------------------------------ΑΛΛΑΓΗ ΟΝΟΜΑΤΟΣ ΜΕ YAD-------------------------------------------
    yad --center --fixed --width=500 --height=100 --image="face-uncertain" --window-icon=gtk-dialog-info --text-align=center --timeout 6 \
    --title="ΑΛΛΑΓΗ ΟΝΟΜΑΤΟΣ" \
    --text="<span font='DejaVu Sans Book 4'>\n</span>\
    <span font='DejaVu Sans Book 12'>Το ονομα ειναι του video ειναι:</span>
    <span color='#CC2222' font='DejaVu Sans Book 12'>${name}</span>
    <span font='DejaVu Sans Book 12'>Θέλετε να αλλάξετε το όνομα;</span>
    <span font='DejaVu Sans Book 12'>Για αλλαγή πατήστε ΟΚ</span>" \
    --button="gtk-quit:252" --button="gtk-cancel:1" --button="gtk-ok:0" 2>/dev/null
    
                 response=$?
    
                 if [[ $response -eq 252 ]]; then
                   exit
                 elif [[ $response -eq 1 ]]; then
                   name="$name"
                 elif [[ $response -eq 0 ]]; then
    
      tmpname=$(mktemp)
      while true; do
       
          yad --center --form --fixed --text-align=center \
          --field="<span color='#0000FF'>Όνομα</span>:H50" '' \
          --width=550 --height=200 --title="Εισαγωγή Ονόματος" \
          --entry-text-maxlen=50 --buttons-layout=center \
          --button="gtk-quit:252" --button="gtk-ok:0" --no-escape \
          --window-icon=insert-link --borders=10 --no-icon 2>/dev/null \
          --text="<span color='#CC2222' font='DejaVu Sans Book 12'>Το παλιό ονομα ειναι: ${name}</span>
    <span font='DejaVu Sans Book 12'>Παρακαλώ εισάγετε το καινούργιο όνομα του βίντεο.
    Στη συνέχεια πατήστε ΟΚ.</span>" > "$tmpname" 2>/dev/null
    
                 response=$?
    
                 if [[ $response -eq 252 ]]; then
                   rm -f "$tmpname"
                   exit
                 elif [ $response -eq 0 ]; then
                   name_input=$(cat "$tmpname")
                   rm -f "$tmpname"
                 fi
    
       name_input=$(echo "$name_input" | sed 's/|//g')
       
    
        # Έλεγχος αν είναι κενό
        if [ -z "$name_input" ]; then
          yad --center --fixed --width=500 --height=100 \
          --image="face-angry" --window-icon=gtk-dialog-warning \
          --title="Warning" --text-align=center --button="gtk-quit:252" --timeout=3 \
          --text="<span font='DejaVu Sans Book 10'>\n</span>\
    <span font='DejaVu Sans Book 10'>\n</span>\
    <span color='#CC2222' font='Sans Bold 12'>Δεν έχει επιλεγεί κάποιο όνομα</span>" 2>/dev/null
    
                 response=$?
    
                 if [[ $response -eq 252 ]]; then
                   rm -f "$tmpname"
                   exit 0
                 fi
      
          continue
        elif [ -n "$name_input" ]; then
          name="$name_input"
          break
        fi
    break
      done
    fi
    
       
    #---------------------------------------ΠΕΡΝΕΙ ΣΕ ΜΕΤΑΒΛΗΤΕΣ ΤΗΣ ΕΠΙΛΟΓΕΣ ΤΩΝ AUDIO KAI VIDEO-------------------------------------------
    
    yad --center \
      --title="Preparing a Video" \
      --text-align=center \
      --window-icon=gtk-dialog-info \
      --button="gtk-quit:252" \
      --fixed \
      --width=550 \
      --height=120 \
      --timeout=3 \
      --image="face-angel" \
      --text="<span font='DejaVu Sans Book 1'>\n</span>
    <span font='DejaVu Sans Book 12'>Γίνεται προετοιμασία</span>
    <span color='#0000FF' font='DejaVu Sans Book 12'>Για το: ${name}</span>
    <span font='DejaVu Sans Book 12'>Παρακαλώ περιμένετε...</span>" 2>/dev/null
    
    
      response=$?
    
      if [[ $response -eq 252 ]]; then
       exit 0
      fi
    
    
      audio=$(yt-dlp -F $links | grep audio)
      readarray -t array_audio <<< "$audio"
    
      video=$(yt-dlp -F $links | grep video)
      readarray -t array_video <<< "$video"
    
    # Έλεγχος εάν υπάρχει best 
    has_best=false
    for entry in "${array_video[@]}"; do
      if [[ "$entry" == *"(best)"* ]]; then
        has_best=true
        break
      fi
    done
    
    # Αν δεν υπάρχει "(best)", πρόσθεσέ το στην τελευταία γραμμή
    if [ "$has_best" = false ]; then
      last_index=$((${#array_video[@]} - 1))
      array_video[$last_index]="${array_video[$last_index]} (best)"
    fi 
    
    #------------------------------------------------Επανελενχος Audio--------------------------------------
    
     if [[ $select -eq 1 ]]; then
       current_audio_array_great=$((current_audio_array+25))
       current_audio_array_litle=$((current_audio_array-25))
    
     for (( m=0; m<${#array_audio[@]}; m++ )); do
       audio_bit=$(echo "${array_audio[$m]}" | sed -n 's/.*audio only[^0-9]*\([0-9]\{2,3\}\)k.*/\1/p')
       audio_bit=$(echo "$audio_bit" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
    
        if [ "$audio_bit" == "$current_audio_array" ] || [ "$audio_bit" -ge "$current_audio_array_litle"  -a  "$audio_bit" -le "$current_audio_array_great" ]; then
              audio_bit=$( echo "${array_audio[$m]}" | sed -n 's/.*audio only[^0-9]*\([0-9]\{2,3\}\)k.*/\1/p' | sed 's/$/k/')
              audio_bit=$(echo "$audio_bit" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
              audio_var=$( echo "${array_audio[$m]}" | sed -n 's/.*audio=\([0-9]\+\).*/audio=\1/p')
              audio_difference=1       
            break
        else
            audio_difference=0
        fi
     done
    
    
    #------------------------------------------------Επανελενχος video--------------------------------------
    
    
    current_video_array1=$( echo $current_video_array | grep -w "(best)" )
    if [ -n "$current_video_array1" ]; then
        
    
       for (( n=0; n<${#array_video[@]}; n++ )); do
         current_video_array2=$( echo "${array_video[$n]}" | grep -w "(best)" | sed -n 's/.*x\([0-9]\+\).*/\1/p' | sed 's/$/ (best)/' )
         if [ -n "$current_video_array2" ]; then
         break
         fi
       done  
    
        if [ "$current_video_array2" == "$current_video_array1" ]; then
          video_bit=$(echo "${array_video[$n]}" | sed -n 's/.*x\([0-9]\+\).*/\1/p' | sed 's/$/p/; s/$/ (best)/' )
          video_var=$(echo "${array_video[$n]}" | sed -n 's/^video=\([0-9]\+\).*/video=\1/p')
          video_difference=1
    
        elif [ "$current_video_array2" != "$current_video_array1" ]; then
          current_video_array1=$(echo "$current_video_array1" | grep -o '[0-9]\+')
          current_video_array2=$(echo "$current_video_array2" | grep -o '[0-9]\+')
          echo $current_video_array1
          echo $current_video_array2 
          current_video_array_great=$((current_video_array1+25))
          current_video_array_litle=$((current_video_array1-25))
    
            if [ "$current_video_array2" -ge "$current_video_array_litle" ] && [ "$current_video_array2" -le "$current_video_array_great" ]; then
             video_bit=$(echo "${array_video[$n]}" | sed -n 's/.*x\([0-9]\+\).*/\1/p' | sed 's/$/p/; s/$/ (best)/' )
             video_var=$(echo "${array_video[$n]}" | sed -n 's/^video=\([0-9]\+\).*/video=\1/p')
             video_difference=1
            else
            video_difference=0
           fi
    
        fi
    
    elif [ -z "$current_video_array1" ]; then
    
          current_video_array_great=$((current_video_array+25))
          current_video_array_litle=$((current_video_array-25))
    
       for (( n=0; n<${#array_video[@]}; n++ )); do
       video_bit2=$(echo "${array_video[$n]}" | sed -n 's/.*x\([0-9]\+\).*/\1/p')
    
        if [ "$video_bit2" == "$current_video_array" ] || [ "$video_bit2" -ge "$current_video_array_litle"  -a  "$video_bit2" -le "$current_video_array_great" ]; then
    
            video_bit=$(echo "${array_video[$n]}" | sed -n 's/.*x\([0-9]\+\).*/\1/p'| sed 's/$/p/')
            video_var=$(echo "${array_video[$n]}" | sed -n 's/^video=\([0-9]\+\).*/video=\1/p')   
            video_difference=1
            break
        else
            video_difference=0
    
        fi
       done
    
    
    fi
    
    #------------------------------------------------Η Διένεξη της δήλωσης σε YAD--------------------------------------
    
      if [[ "$audio_difference" -eq 0 && "$video_difference" -eq 0 ]]; then
    
         yad --center --fixed --title="Difference a Video/Audio" --text="<span font='DejaVu Sans Book 16'>\n</span>\
    <span color='#CC2222' font='DejaVu Sans Book 12'>Υπάρχει διένεξη της δήλωσης του video-audio με πριν.
    Πρέπει να δηλωθεί πάλι.</span>" \
    --window-icon=gtk-dialog-info --text-align=center --image="face-devilish" --no-buttons --width=550 --height=100 --timeout 4 2>/dev/null
    
      response=$?
    
          if [[ $response -eq 252 ]]; then
            exit 0
          fi
    
        select=0
    
      elif [[ "$audio_difference" -eq 0 && "$video_difference" -eq 1 ]]; then 
    
         yad --center --fixed --title="Difference a Audio" --text="<span font='DejaVu Sans Book 16'>\n</span>\
    <span color='#CC2222' font='DejaVu Sans Book 12'>Υπάρχει διένεξη της δήλωσης του audio με πριν.
    Πρέπει να δηλωθεί πάλι.</span>" \
    --window-icon=gtk-dialog-info --text-align=center --image="face-devilish" --no-buttons --width=550 --height=100 --timeout 4 2>/dev/null
    
      response=$?
    
          if [[ $response -eq 252 ]]; then
            exit 0
          fi
    
        select=0
    
      elif [[ "$audio_difference" -eq 1 && "$video_difference" -eq 0 ]]; then 
    
         yad --center --fixed --title="Preparing a Video" --text="<span font='DejaVu Sans Book 16'>\n</span>\
    <span color='#CC2222' font='DejaVu Sans Book 12'>Υπάρχει διένεξη της δήλωσης του video με πριν.
    Πρέπει να δηλωθεί πάλι.</span>" \
    --window-icon=gtk-dialog-info --text-align=center --image="face-devilish" --no-buttons --width=550 --height=100 --timeout 4 2>/dev/null
     
      response=$?
    
          if [[ $response -eq 252 ]]; then
            exit 0
          fi
    
        select=0
    
      elif [[ "$audio_difference" -eq 1 && "$video_difference" -eq 1 ]]; then 
       select=1
      fi
    
     fi
    
    
    
    #----------------------------------------------------ΕΠΙΛΟΓΗ "MENU" AUDIO -----------------------------------------------------------
    
      if [[ $select -eq 0 ]]; then
    
    tmpaudio=$(mktemp)
    
    while true; do
      audio_bitrate_list=()
    
      # Δημιουργία λίστας με καθαρά bitrate (π.χ. 128k, 256k)
      for audio_bitrate in "${array_audio[@]}"; do
        audio_bit1=$(echo "$audio_bitrate"  | sed -n 's/.*audio only[^0-9]*\([0-9]\{2,3\}\)k.*/\1/p' | sed 's/$/k/')
        audio_bitrate_list+=("$audio_bit1")
      done
    
      #Παρουσίαση YAD Εμφάνιση επιλογών
        yad --center --title="Επιλογή ήχου" --list --borders=10 --no-headers --image="sound" --window-icon=media-audio \
        --width=500 --height=260 --column=List --button="gtk-quit:252" --button="gtk-cancel:1" --button="gtk-ok:0" \
        --text="<span font='DejaVu Sans Book 4'>\n</span> \
    <span font='DejaVu Sans Book 11'>Επίλεξε ένα στοιχείο Bitrate για ήχο από τη λίστα</span>" \
    "${audio_bitrate_list[@]}" > "$tmpaudio" 2>/dev/null
    
              response=$?
    
             if [[ $response -eq 252 ]]; then
                rm -f "$tmpaudio"
                exit
             fi
             if [[ $response -eq 0 ]]; then
               selected_audio=$(cat "$tmpaudio")
               selected_audio=$(echo "$selected_audio" | tr -d '|')
               rm -f "$tmpaudio"
               break
             fi
             if [[ $response -eq 1 ]]; then
              yad --center --fixed --width=500 --height=100 --image=dialog-warning --window-icon=gtk-dialog-warning --title="Warning" \
              --text-align=center --button="gtk-quit:252" --timeout 3 --text="<span font='DejaVu Sans Book 4'>\n</span>\
              <span font='DejaVu Sans Book 4'>\n</span>\
    <span color='#CC2222' font='Sans Bold 12'>Δεν έχει γίνει επιλογή Bitrate για ήχο</span>" 2>/dev/null
    
           response=$?
    
                 if [[ $response -eq 252 ]]; then
                   rm -f "$tmpaudio"
                   exit 0
                 else
                   continue
                 fi
             fi
    
    done
    
      # -----------------------------Εύρεση του bitrate και του format ID που ταιριάζει στην επιλογή audio
      i=0
      for audio_bitrate in "${array_audio[@]}"; do
        audio_bit=$(echo "$audio_bitrate" | sed -n 's/.*audio only[^0-9]*\([0-9]\{2,3\}\)k.*/\1/p' | sed 's/$/k/')
        
        if [ "$selected_audio" == "$audio_bit" ]; then
           audio_var=$(echo "${array_audio[$i]}" | sed -n 's/.*audio=\([0-9]\+\).*/audio=\1/p')
          break
        fi
        i=$((i+1))
      done
    
    #bitrate μόνο η τιμή
     current_audio_array=$( echo "${array_audio[$i]}" | sed -n 's/.*audio only[^0-9]*\([0-9]\{2,3\}\)k.*/\1/p')
    #----------------------------------------------------ΕΠΙΛΟΓΗ "MENU" VIDEO-----------------------------------------------------------
    tmpvideo=$(mktemp)
    
    while true; do
      video_list=()
    
    
    
        for video_bitrate in "${array_video[@]}"; do
          video_resource=$( echo "$video_bitrate" | grep -w "(best)" )
          video_bit1=$(echo "${video_bitrate}" | sed -n 's/.*x\([0-9]\+\).*/\1/p'| sed 's/$/p/')
          if [ -z "$video_resource" ]; then
            video_bit1="${video_bit1}"
          elif [ -n "$video_resource" ]; then
            video_bit1="${video_bit1} (best)"
          fi
    
        video_list+=("$video_bit1")
    
        done
    
       #Παρουσίαση YAD Εμφάνιση επιλογών
    
        yad --center --title="Επιλογή Βίντεο" --list \
        --text="<span font='DejaVu Sans Book 4'>\n</span> \
    <span font='DejaVu Sans Book 11'>Επίλεξε ένα στοιχείο Resolution για βίντεο από τη λίστα</span>" \
        --borders=10 --image="video-x-generic" --no-headers --window-icon=media-video \
        --button="gtk-quit:252" --button="gtk-cancel:1" --button="gtk-ok:0" \
        --width=500 --height=260 --column=List "${video_list[@]}" > "$tmpvideo" 2>/dev/null
      
              response=$?
    
              if [[ $response -eq 252 ]]; then
                rm -f "$tmpvideo"
                exit
             fi
             if [[ $response -eq 0 ]]; then
               selected_video=$(cat "$tmpvideo")
               selected_video=$(echo "$selected_video" | tr -d '|')
               rm -f "$tmpvideo"
               break
             fi
             if [[ $response -eq 1 ]]; then
              yad --center --fixed --width=500 --height=100 --image=dialog-warning  --window-icon=gtk-dialog-warning --title="Warning" \
              --text-align=center --button="gtk-quit:252" --timeout 3 --text="<span font='DejaVu Sans Book 4'>\n</span>\
              <span font='DejaVu Sans Book 4'>\n</span>\
    <span color='#CC2222' font='Sans Bold 12'>Δεν έχει γίνει επιλογή Resolution για βίντεο</span>" 2>/dev/null
    
              response=$?
    
                if [[ $response -eq 252 ]]; then
                  rm -f "$tmpvideo"
                  exit 0
                else
                  continue
                fi
    
             fi
    
        done
        
    # --------------------------Εύρεση του resolution και του format ID που ταιριάζει στην επιλογή video
         v=0
          for video_bitrate in "${array_video[@]}"; do
          video_resource=$( echo "$video_bitrate" | grep -w "(best)" )
          video_bit1=$(echo "${video_bitrate}" | sed -n 's/.*x\([0-9]\+\).*/\1/p'| sed 's/$/p/')
          #video_bit1=$(echo "$video_bit1" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
    
          if [ -z "$video_resource" ]; then
            if [ "$selected_video" == "$video_bit1" ]; then
               video_bit=$(echo "${array_video[$v]}" | sed -n 's/.*x\([0-9]\+\).*/\1/p'| sed 's/$/p/')
               video_var=$(echo "${array_video[$v]}" | sed -n 's/^video=\([0-9]\+\).*/video=\1/p')
               break
            fi
    
          elif [ -n "$video_resource" ]; then
            video_bit1="${video_bit1} (best)"
            if [ "$selected_video" == "$video_bit2" ]; then
               video_bit=$(echo "${array_video[$v]}" | sed -n 's/.*x\([0-9]\+\).*/\1/p'| sed 's/$/p/; s/$/ (best)/')
               video_var=$(echo "${array_video[$v]}" | sed -n 's/^video=\([0-9]\+\).*/video=\1/p')
               break
            fi
    
          fi
             v=$((v+1))
          done
    
    #resolution που κραταει
    if [ -z "$video_resource" ]; then
    current_video_array=$( echo ${array_video[$v]} | sed -n 's/.*x\([0-9]\+\).*/\1/p')
    elif [ -n "$video_resource" ]; then
    current_video_array=$( echo ${array_video[$v]} | sed -n 's/.*x\([0-9]\+\).*/\1/p' | sed 's/$/ (best)/')
    fi
    
    #-------------------------------------------Επιλογή φακέλου αποθήκευσης-----------------------------------------------------------------
    tempdir=$(mktemp)
     while true; do
    
          yad --file-selection --directory  --text-align=center --title="Φάκελοι" --text-align=center --text="<span font='DejaVu Sans Book 4'>\n</span>\
    <span color='#0000FF' font='DejaVu Sans Book 12'>Επιλογή φακέλου αποθήκευσης</span>" --window-icon=gtk-directory --center --width=900 --height=900 --on-top \
    --button="gtk-quit:252" --button="gtk-cancel:1" --button="gtk-ok:0" > "$tempdir" 2>/dev/null
    
              response=$?
    
             if [[ $response -eq 252 ]]; then
                 rm -f "$tempdir"
                 exit
             fi
    
             if [[ $response -eq 0 ]]; then
             output_dir=$(cat "$tempdir")
             output_dir=$(echo "$output_dir" | tr -d '|')
             rm -f "$tempdir"
               break
             fi
    
            if [[ $response -eq 1 ]]; then
          yad --center --fixed --width=500 --height=100 --image="face-tired" --window-icon=gtk-dialog-warning --title="Warning" \
    --text-align=center --button="gtk-quit:252" --timeout 3 --text="<span font='DejaVu Sans Book 4'>\n</span>\
    <span font='DejaVu Sans Book 4'>\n</span>\
    <span color='#CC2222' font='Sans Bold 12'>
    Δεν επιλέχθηκε φάκελος αποθήκευσης</span>" 2>/dev/null
    
              response=$?
    
              if [[ $response -eq 252 ]]; then
                rm -f "$tempdir"
                exit 0
              else
               continue
              fi
    
            fi
    
     done
    
    
       yad --center --fixed --width=600 --height=200 --text="<span font='DejaVu Sans Book 12'>
    Ονομα: ${name}
    Επιλογή Ήχου: ${audio_bit} ${audio_var}
    Επιλογή Βίντεο: ${video_bit} ${video_var}
    Επιλογή Φακέλου αποθήκευσης: 
    ${output_dir}'</span>\n \
    <span color='#CC2222' font='DejaVu Sans Book 12'>Θέλετε να της κρατήσετε οριστικά;</span>" \
    --image="face-uncertain" --text-align=center --button="gtk-quit:252" --button="gtk-no:1" --button="gtk-yes:0" 2>/dev/null
    
    response=$?
    
         if [[ $response -eq 252 ]]; then
          exit 0
         elif [[ $response -eq 0 ]]; then
          select=1
         elif [[ $response -eq 1 ]]; then
          select=0
         fi
    
      fi
    
    
    #--------τελος if select=0 ----------------------Downloading Video/Audio--------------------------------------------------------
    
      video=$(echo "${video_var}[ext=mp4]+${audio_var}[ext=m4a]/bestvideo+bestaudio")
    
     (
      yt-dlp -f $video -o "$output_dir/${name}.${video_bit}-${audio_bit}.ERTFLIX.%(ext)s" --merge-output-format mp4  $links --newline \
      | while read -r line; do
            progress=$(echo "$line" | grep --line-buffered -oP '^\[download\].*?\K([0-9.]+\%|#\d+ of \d)')
            if [[ -n $progress ]]; then
                percent=$(echo "$progress" | grep -oP '[0-9.]+')
                new_percent=$(awk -v p="$percent" 'BEGIN{printf "%.0f%%", p-0.8}')
                echo "$new_percent"
            fi
            echo "$line"
        done \
    | tee >(grep "%" | sed -u "s/\(.*\)%\ \([0-9\.]*\)\(.*\)/\2\n# \1\2% \3/") \
    ) | yad --center --width=550 --height=100 --progress --title="Downloading Video/Audio..." --text="<span font='DejaVu Sans Book 4'>\n</span> \
    <span font='DejaVu Sans Book 11'>Please wait..${name}: ${video_bit} - ${audio_bit}</span>" \
     --auto-close --no-buttons --borders=10 --scroll 2>/dev/null
    
    #-----------------------------------------Download completed--Abort Download--OR--NOT-------------------------------------------------
    
    
      yad --center --info --fixed --image="face-kiss" --no-buttons --title="Download Complete" --text-align=center --text="<span font='DejaVu Sans Book 16'>\n</span> \
    <span color='#0000FF' font='DejaVu Sans Book 12'>Download completed successfully! \n ${name}</span>" --width=500 --height=100 --timeout 5 2>/dev/null
    
         delete_line=1
         sed -i "${delete_line}d" /home/${USER}/ARRAY_ERTFLIX
         
         y=$((y+1))
         mapfile -t Array_Series_ERTFLIX < /home/${USER}/ARRAY_ERTFLIX
    
          if [[ "${#Array_Series_ERTFLIX[@]}" -gt 1 && "$y" -ge 1 ]]; then
           yad --center --fixed --text-align=center --width=500 --height=50 \
           --title="Abort Download" \
           --text="<span font='DejaVu Sans Book 18'>\n</span>Επέλεξε Ναι για σταμάτημα." \
           --button="Ναι":0 \
           --timeout=7 2>/dev/null
    
     response=$?
    
         if [[ $response -eq 252 ]]; then
          exit 0 
         elif [[ $response -eq 0 ]]; then
         yad --center --fixed --image="face-sad"  --text-align=center --width=500 --height=80 --no-buttons --title="Download Complete All" \
    --text="<span font='DejaVu Sans Book 12'>\n</span> \
    <span color='#CC2222' font='DejaVu Sans Book 12'>Download aborted</span>"  --timeout 3 2>/dev/null
          exit
          else
          yad --center --fixed --image="face-smile-big"  --text-align=center --width=500 --height=80 --no-buttons --title="Download Complete All" \
    --text="<span font='DejaVu Sans Book 12'>\n</span> \
    <span color='#0000FF' font='DejaVu Sans Book 12'>Continuing download...</span>"  --timeout 3 2>/dev/null
             break 1
            fi
          fi
    
      done
    
    #-----------------------------------------END-------------------------------------------------
    
    elif [[ "${#Array_Series_ERTFLIX[@]}" -eq 0 ]]; then
    yad --center --info --fixed --image="face-cool" --text-align=center --width=500 --height=100 --no-buttons --title="Download Complete All" --text="<span font='DejaVu Sans Book 12'>\n</span> \
    <span color='#0000FF' font='DejaVu Sans Book 12'>Δεν υπάρχουν links για κατέβασμα\n \
    Φτάσατε στο τέλος</span>"  --timeout 5 2>/dev/null
    
     response=$?
    
         if [[ $response -eq 252 ]]; then
          exit 0
         fi
    exit
    
    fi
    done
    
    fi
    Τελευταία επεξεργασία από το μέλος microvio : 17-05-25 στις 08:29.

  5. #305
    Εγγραφή
    08-03-2007
    Μηνύματα
    25.648
    Downloads
    26
    Uploads
    0
    ISP
    ΟΤΕ Conn-x
    Αλλαξε το [code ] στο τελος σε [/code ] (χωρις τα κενα προφανως) για να δουλεψουν τα code tags και να διαβαζεται.
    ديميتريس

  6. #306
    Εγγραφή
    22-01-2014
    Περιοχή
    ΘεΣσΑλΟνΙκΙ
    Μηνύματα
    1.218
    Downloads
    1
    Uploads
    0
    Τύπος
    VDSL2
    Ταχύτητα
    50M/5M
    ISP
    ΟΤΕ Conn-x
    DSLAM
    ΟΤΕ - ΠΑΥΛΟΥ ΜΕΛΑ
    Router
    DN9245X6-10
    SNR / Attn
    12.7(dB) / 25.1(dB)
    To αντίστοιχο python gui script για Windows!

    Εγκατάσταση της Python (με την επιλογή "Add Python to PATH").
    Λήψη του yt-dlp.exe και τοποθέτησή του είτε στον ίδιο φάκελο με το script είτε σε έναν φάκελο που βρίσκεται στο PATH.

    Αποθηκεύστε τον παρακάτω κώδικα ως ένα αρχείο Python (π.χ., ertflix_gui_downloader.py).
    Κατεβάστε το yt-dlp.exe από την επίσημη σελίδα του (https://github.com/yt-dlp/yt-dlp/rel...oad/yt-dlp.exe) και τοποθετήστε το στον ίδιο φάκελο με το ertflix_gui_downloader.py.
    Ανοίξτε μια γραμμή εντολών (Command Prompt ή PowerShell) στον φάκελο όπου αποθηκεύσατε τα αρχεία και εκτελέστε:
    python ertflix_gui_downloader.py
    Χρήση Εφαρμογής:
    Εισάγετε έναν σύνδεσμο ERTFlix στο πεδίο και πατήστε "Προσθήκη" (ή Enter).
    Οι σύνδεσμοι θα εμφανιστούν στη λίστα.
    Πατήστε "Έναρξη Λήψεων".
    Για κάθε σύνδεσμο, θα εμφανιστεί ένα παράθυρο διαλόγου για να:
    Επιβεβαιώσετε/αλλάξετε το όνομα του αρχείου.
    Επιλέξετε ποιότητα βίντεο.
    Επιλέξετε ποιότητα ήχου.
    Επιλέξετε φάκελο αποθήκευσης (ο τελευταίος φάκελος αποθηκεύεται).
    Πατήστε "ΟΚ" στο διάλογο για να ξεκινήσει η λήψη του συγκεκριμένου βίντεο.
    Η γραμμή προόδου και η κατάσταση θα ενημερώνονται.
    Μπορείτε να πατήσετε "Διακοπή" για να σταματήσετε την τρέχουσα λήψη και τις επόμενες.
    "Αφαίρεση Επιλεγμένου" και "Εκκαθάριση Λίστας" διαχειρίζονται τη λίστα συνδέσμων.
    Οι σύνδεσμοι αποθηκεύονται στο ertflix_links.txt και ο τελευταίος φάκελος λήψης στο downloader_config.json

    Δεν χρειάζεται να εγκαταστήσετε επιπλέον πακέτα Python μέσω pip (όπως pip install some_package) για να τρέξει αυτό το συγκεκριμένο script, καθώς όλες οι χρησιμοποιούμενες βιβλιοθήκες Python είναι μέρος της standard library.

    Κώδικας:
    import tkinter as tk
    from tkinter import ttk, filedialog, messagebox
    import subprocess
    import threading
    import os
    import re
    import json
    
    # --- Configuration ---
    YT_DLP_PATH = "yt-dlp.exe"  # Or full path if not in same directory/PATH
    LINKS_FILE = "ertflix_links.txt"
    CONFIG_FILE = "downloader_config.json" # Για αποθήκευση τελευταίου φακέλου
    
    class ErtflixDownloaderApp:
        def __init__(self, root):
            self.root = root
            self.root.title("ERTFlix Downloader")
            self.root.geometry("800x600")
    
            self.links_to_download = []
            self.current_download_thread = None
            self.stop_download_flag = threading.Event()
            self.last_save_directory = self.load_last_config().get("last_save_directory", os.path.expanduser("~\\Downloads"))
            self.last_audio_quality_id = None # Θα αποθηκεύουμε το ID του format
            self.last_video_quality_id = None # Θα αποθηκεύουμε το ID του format
    
            self.setup_ui()
            self.load_links_from_file()
    
        def load_last_config(self):
            if os.path.exists(CONFIG_FILE):
                try:
                    with open(CONFIG_FILE, 'r', encoding='utf-8') as f:
                        return json.load(f)
                except json.JSONDecodeError:
                    return {}
                except Exception: # Catch other potential errors during file reading
                    return {}
            return {}
    
        def save_last_config(self):
            config = {
                "last_save_directory": self.last_save_directory,
                "last_audio_quality_id": self.last_audio_quality_id,
                "last_video_quality_id": self.last_video_quality_id
                }
            try:
                with open(CONFIG_FILE, 'w', encoding='utf-8') as f:
                    json.dump(config, f)
            except Exception as e:
                print(f"Error saving config: {e}")
    
    
        def setup_ui(self):
            # --- Frame for Link Input ---
            input_frame = ttk.LabelFrame(self.root, text="Εισαγωγή Συνδέσμου ERTFlix")
            input_frame.pack(padx=10, pady=10, fill="x")
    
            self.link_entry = ttk.Entry(input_frame, width=80)
            self.link_entry.pack(side=tk.LEFT, padx=5, pady=5, expand=True, fill="x")
            self.link_entry.bind("<Return>", lambda event: self.add_link())
    
    
            add_button = ttk.Button(input_frame, text="Προσθήκη", command=self.add_link)
            add_button.pack(side=tk.LEFT, padx=5, pady=5)
    
            # --- Frame for Links List ---
            list_frame = ttk.LabelFrame(self.root, text="Λίστα Συνδέσμων")
            list_frame.pack(padx=10, pady=5, fill="both", expand=True)
    
            self.links_listbox = tk.Listbox(list_frame, selectmode=tk.SINGLE, width=100, height=15)
            self.links_listbox.pack(side=tk.LEFT, padx=5, pady=5, fill="both", expand=True)
    
            scrollbar = ttk.Scrollbar(list_frame, orient="vertical", command=self.links_listbox.yview)
            scrollbar.pack(side=tk.RIGHT, fill="y")
            self.links_listbox.config(yscrollcommand=scrollbar.set)
    
            # --- Frame for Controls ---
            controls_frame = ttk.Frame(self.root)
            controls_frame.pack(padx=10, pady=5, fill="x")
    
            self.start_button = ttk.Button(controls_frame, text="Έναρξη Λήψεων", command=self.start_download_process)
            self.start_button.pack(side=tk.LEFT, padx=5, pady=5)
    
            self.stop_button = ttk.Button(controls_frame, text="Διακοπή", command=self.stop_current_download, state=tk.DISABLED)
            self.stop_button.pack(side=tk.LEFT, padx=5, pady=5)
            
            remove_selected_button = ttk.Button(controls_frame, text="Αφαίρεση Επιλεγμένου", command=self.remove_selected_link)
            remove_selected_button.pack(side=tk.LEFT, padx=5, pady=5)
    
            clear_button = ttk.Button(controls_frame, text="Εκκαθάριση Λίστας", command=self.clear_links)
            clear_button.pack(side=tk.LEFT, padx=5, pady=5)
    
    
            # --- Frame for Progress and Status ---
            status_frame = ttk.LabelFrame(self.root, text="Κατάσταση")
            status_frame.pack(padx=10, pady=10, fill="x")
    
            self.status_label = ttk.Label(status_frame, text="Έτοιμο.")
            self.status_label.pack(side=tk.LEFT, padx=5, pady=5)
    
            self.progress_bar = ttk.Progressbar(status_frame, orient="horizontal", length=300, mode="determinate")
            self.progress_bar.pack(side=tk.LEFT, padx=5, pady=5, expand=True, fill="x")
    
    
        def add_link(self):
            link = self.link_entry.get().strip()
            if link:
                if link.startswith("http://") or link.startswith("https://"):
                    if link not in self.links_to_download:
                        self.links_to_download.append(link)
                        self.links_listbox.insert(tk.END, link)
                        self.link_entry.delete(0, tk.END)
                        self.save_links_to_file()
                    else:
                        messagebox.showwarning("Διπλότυπο", "Αυτός ο σύνδεσμος υπάρχει ήδη στη λίστα.")
                else:
                    messagebox.showerror("Σφάλμα", "Μη έγκυρος σύνδεσμος. Πρέπει να ξεκινά με http:// ή https://")
            else:
                messagebox.showwarning("Κενό Πεδίο", "Παρακαλώ εισάγετε έναν σύνδεσμο.")
    
        def remove_selected_link(self):
            selected_indices = self.links_listbox.curselection()
            if not selected_indices:
                messagebox.showinfo("Καμία Επιλογή", "Δεν έχετε επιλέξει σύνδεσμο για αφαίρεση.")
                return
    
            selected_index = selected_indices[0]
            link_to_remove = self.links_listbox.get(selected_index)
            
            if messagebox.askyesno("Επιβεβαίωση Αφαίρεσης", f"Θέλετε σίγουρα να αφαιρέσετε τον σύνδεσμο:\n{link_to_remove} ;"):
                self.links_listbox.delete(selected_index)
                if link_to_remove in self.links_to_download:
                     self.links_to_download.remove(link_to_remove)
                self.save_links_to_file()
                self.status_label.config(text=f"Αφαιρέθηκε: {link_to_remove}")
    
    
        def load_links_from_file(self):
            self.links_to_download.clear()
            self.links_listbox.delete(0, tk.END)
            if os.path.exists(LINKS_FILE):
                try:
                    with open(LINKS_FILE, "r", encoding="utf-8") as f:
                        for line in f:
                            link = line.strip()
                            if link and link not in self.links_to_download : 
                                self.links_to_download.append(link)
                                self.links_listbox.insert(tk.END, link)
                except Exception as e:
                    messagebox.showerror("Σφάλμα Φόρτωσης", f"Δεν ήταν δυνατή η φόρτωση συνδέσμων: {e}")
    
    
        def save_links_to_file(self):
            try:
                with open(LINKS_FILE, "w", encoding="utf-8") as f:
                    for link in self.links_to_download:
                        f.write(link + "\n")
            except Exception as e:
                messagebox.showerror("Σφάλμα Αποθήκευσης", f"Δεν ήταν δυνατή η αποθήκευση συνδέσμων: {e}")
    
        def clear_links(self):
            if messagebox.askyesno("Εκκαθάριση", "Είστε σίγουροι ότι θέλετε να αφαιρέσετε όλους τους συνδέσμους;"):
                self.links_to_download.clear()
                self.links_listbox.delete(0, tk.END)
                self.save_links_to_file()
                self.status_label.config(text="Η λίστα εκκαθαρίστηκε.")
    
        def start_download_process(self):
            if not self.links_to_download:
                messagebox.showinfo("Κενή Λίστα", "Δεν υπάρχουν σύνδεσμοι για λήψη.")
                return
    
            if self.current_download_thread and self.current_download_thread.is_alive():
                messagebox.showwarning("Σε Εξέλιξη", "Μια λήψη είναι ήδη σε εξέλιξη.")
                return
                
            self.start_button.config(state=tk.DISABLED)
            self.stop_button.config(state=tk.NORMAL)
            self.stop_download_flag.clear()
    
            # Φόρτωση των τελευταίων επιλογών ποιότητας πριν την έναρξη
            config = self.load_last_config()
            self.last_audio_quality_id = config.get("last_audio_quality_id")
            self.last_video_quality_id = config.get("last_video_quality_id")
    
    
            self.current_download_thread = threading.Thread(target=self._download_worker, daemon=True)
            self.current_download_thread.start()
    
        def stop_current_download(self):
            if self.current_download_thread and self.current_download_thread.is_alive():
                self.status_label.config(text="Προσπάθεια διακοπής...")
                self.stop_download_flag.set() 
    
        def _download_worker(self):
            initial_links_count = len(self.links_to_download)
            downloaded_count = 0
    
            while self.links_to_download and not self.stop_download_flag.is_set():
                link_to_process = self.links_to_download[0]
                self.root.after_idle(lambda l=link_to_process: self.status_label.config(text=f"Επεξεργασία: {l[:50]}..."))
                self.root.after_idle(lambda: self.progress_bar.config(value=0))
    
                video_info = None 
                try:
                    proc = subprocess.run(
                        [YT_DLP_PATH, "-F", "--no-warnings", "--dump-json", "--encoding", "utf-8", link_to_process],
                        capture_output=True, text=True, encoding='utf-8', # Ensure utf-8 for output
                        creationflags=subprocess.CREATE_NO_WINDOW if os.name == 'nt' else 0
                    )
                    
                    # print(f"DEBUG: yt-dlp return code for {link_to_process}: {proc.returncode}")
                    # print(f"DEBUG: yt-dlp stdout for {link_to_process}:\n>>>\n{proc.stdout}\n<<<")
                    # print(f"DEBUG: yt-dlp stderr for {link_to_process}:\n>>>\n{proc.stderr}\n<<<")
    
                    if proc.returncode != 0:
                        error_message = f"Το yt-dlp απέτυχε για το {link_to_process} (code: {proc.returncode}).\n"
                        if proc.stderr:
                            error_message += f"Stderr:\n{proc.stderr[:500]}"
                        elif proc.stdout: 
                            error_message += f"Stdout:\n{proc.stdout[:500]}"
                        else:
                            error_message += "Δεν υπήρξε έξοδος σφάλματος."
                        self.root.after_idle(lambda msg=error_message: messagebox.showerror("Σφάλμα yt-dlp", msg))
                        self.root.after_idle(self._mark_link_as_failed, link_to_process)
                        continue
    
                    if not proc.stdout or not proc.stdout.strip():
                        self.root.after_idle(lambda l=link_to_process: messagebox.showerror("Σφάλμα yt-dlp", f"Το yt-dlp δεν επέστρεψε δεδομένα (κενή έξοδος) για το {l}."))
                        self.root.after_idle(self._mark_link_as_failed, link_to_process)
                        continue
                    
                    potential_json_lines = proc.stdout.strip().splitlines()
                    parsed_successfully = False
                    for line_content in potential_json_lines:
                        try:
                            video_info_candidate = json.loads(line_content)
                            if isinstance(video_info_candidate, dict) and 'formats' in video_info_candidate:
                                video_info = video_info_candidate
                                parsed_successfully = True
                                break 
                        except json.JSONDecodeError:
                            continue 
    
                    if not parsed_successfully or video_info is None:
                        self.root.after_idle(lambda l=link_to_process, out=proc.stdout[:500]: messagebox.showerror("Σφάλμα Ανάλυσης JSON", f"Δεν ήταν δυνατή η ανάλυση της εξόδου JSON από το yt-dlp για το {l}.\nΈξοδος:\n{out}"))
                        self.root.after_idle(self._mark_link_as_failed, link_to_process)
                        continue
    
                except json.JSONDecodeError as e_json: # Should be caught by the inner try-except now
                     self.root.after_idle(lambda l=link_to_process, err=str(e_json), out_data=proc.stdout[:500] if 'proc' in locals() else "N/A": messagebox.showerror("Σφάλμα Ανάλυσης JSON", f"Σφάλμα κατά την ανάλυση JSON για {l}:\n{err}\n\nΠρώτες γραμμές εξόδου:\n{out_data}"))
                     self.root.after_idle(self._mark_link_as_failed, link_to_process)
                     continue
                except Exception as e: 
                    self.root.after_idle(lambda l=link_to_process, err=str(e): messagebox.showerror("Γενικό Σφάλμα", f"Άγνωστο σφάλμα κατά την επεξεργασία του {l}:\n{err}"))
                    self.root.after_idle(self._mark_link_as_failed, link_to_process)
                    continue
    
                if not video_info: 
                    self.root.after_idle(lambda l=link_to_process: messagebox.showerror("Σφάλμα Δεδομένων", f"Δεν ανακτήθηκαν πληροφορίες βίντεο για το {l}."))
                    self.root.after_idle(self._mark_link_as_failed, link_to_process)
                    continue
    
                dialog_result = self.show_format_selection_dialog(video_info)
    
                if not dialog_result or self.stop_download_flag.is_set(): 
                    if not self.stop_download_flag.is_set(): 
                         self.root.after_idle(lambda: self.status_label.config(text="Η λήψη ακυρώθηκε από τον χρήστη."))
                    break 
    
                output_name = dialog_result["name"]
                save_dir = dialog_result["path"]
                video_format_id = dialog_result["video_id"]
                audio_format_id = dialog_result["audio_id"]
                
                self.last_save_directory = save_dir 
                self.last_audio_quality_id = audio_format_id
                self.last_video_quality_id = video_format_id
                self.save_last_config()
    
    
                output_template = os.path.join(save_dir, f"{output_name}.%(ext)s")
                format_selection = f"{video_format_id}+{audio_format_id}/bv*+ba/b"
    
                try:
                    cmd = [
                        YT_DLP_PATH,
                        "-f", format_selection,
                        "--no-warnings",
                        "--progress", 
                        "--newline", 
                        "--merge-output-format", "mp4", 
                        "-o", output_template,
                        link_to_process
                    ]
                    
                    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                                               text=True, encoding='utf-8', bufsize=1, universal_newlines=True,
                                               creationflags=subprocess.CREATE_NO_WINDOW if os.name == 'nt' else 0)
    
                    for line in process.stdout:
                        if self.stop_download_flag.is_set():
                            process.terminate() 
                            try:
                                process.wait(timeout=5) 
                            except subprocess.TimeoutExpired:
                                process.kill() 
                            self.root.after_idle(lambda: self.status_label.config(text="Η λήψη διακόπηκε."))
                            break 
    
                        match = re.search(r"\[download\]\s+([0-9\.]+?%)\s+of", line)
                        if match:
                            percent_str = match.group(1).replace('%', '')
                            try:
                                percent = float(percent_str)
                                self.root.after_idle(lambda p=percent: self.progress_bar.config(value=p))
                                self.root.after_idle(lambda p=percent, n=output_name: self.status_label.config(text=f"Λήψη {n}: {p:.1f}%"))
                            except ValueError:
                                pass 
                    process.wait() 
    
                    if self.stop_download_flag.is_set():
                        break 
    
                    if process.returncode == 0:
                        self.root.after_idle(lambda n=output_name: self.status_label.config(text=f"Η λήψη του '{n}' ολοκληρώθηκε."))
                        self.root.after_idle(self._mark_link_as_done, link_to_process)
                        downloaded_count += 1
                    else:
                        stderr_output = process.stderr.read() if process.stderr else "No stderr output"
                        self.root.after_idle(lambda n=output_name, err=stderr_output: messagebox.showerror("Σφάλμα Λήψης", f"Σφάλμα κατά τη λήψη του '{n}':\n{err[:500]}"))
                        self.root.after_idle(self._mark_link_as_failed, link_to_process) 
    
                except Exception as e:
                    self.root.after_idle(lambda l=link_to_process, err=str(e): messagebox.showerror("Σφάλμα Εκτέλεσης", f"Σφάλμα κατά την εκτέλεση λήψης για {l}:\n{err}"))
                    self.root.after_idle(self._mark_link_as_failed, link_to_process)
                    continue 
                
                if self.stop_download_flag.is_set():
                    self.root.after_idle(lambda: self.status_label.config(text="Οι λήψεις διακόπηκαν."))
                    break
    
            self.root.after_idle(self._on_all_downloads_finished, downloaded_count, initial_links_count)
    
    
        def _mark_link_as_done(self, link):
            if link in self.links_to_download:
                try:
                    idx = self.links_to_download.index(link)
                    self.links_listbox.delete(idx)
                    self.links_to_download.pop(idx)
                    self.save_links_to_file()
                except ValueError: # Link might have been removed by another action
                    pass
                except Exception as e:
                    print(f"Error marking link as done: {e}")
    
    
        def _mark_link_as_failed(self, link):
            if link in self.links_to_download:
                try:
                    idx = self.links_to_download.index(link)
                    self.links_listbox.itemconfig(idx, {'bg':'#FFCCCC', 'fg':'#A60000'}) # Light red background
                except ValueError:
                     pass # Link not in listbox (maybe already removed)
                except Exception as e:
                    print(f"Error marking link as failed in listbox: {e}")
                # We don't remove it automatically, user can retry or remove manually
    
    
        def _on_all_downloads_finished(self, downloaded_count, initial_count):
            self.start_button.config(state=tk.NORMAL)
            self.stop_button.config(state=tk.DISABLED)
            self.progress_bar.config(value=0)
            if not self.stop_download_flag.is_set():
                if initial_count > 0: # Only show messages if there were links to process
                    if downloaded_count == initial_count:
                        self.status_label.config(text="Όλες οι λήψεις ολοκληρώθηκαν!")
                        messagebox.showinfo("Ολοκλήρωση", "Όλες οι λήψεις ολοκληρώθηκαν με επιτυχία!")
                    else:
                        failed_count = initial_count - downloaded_count - (len(self.links_to_download) if self.links_to_download else 0)
                        # Correct failed count calculation might be more complex if items are not removed on fail
                        self.status_label.config(text=f"Ολοκληρώθηκαν {downloaded_count} από {initial_count} λήψεις.")
                        messagebox.showwarning("Μερική Ολοκλήρωση", f"Ολοκληρώθηκαν {downloaded_count} από {initial_count} λήψεις.\nΕλέγξτε τη λίστα για τυχόν αποτυχίες (κόκκινο χρώμα).")
                elif not self.links_to_download and initial_count == 0 :
                     self.status_label.config(text="Έτοιμο. Δεν υπάρχουν σύνδεσμοι στη λίστα.")
            else:
                 self.status_label.config(text="Οι λήψεις διακόπηκαν από τον χρήστη.")
            self.current_download_thread = None 
    
        def show_format_selection_dialog(self, video_info):
            dialog = tk.Toplevel(self.root)
            dialog.title("Επιλογή Μορφής & Ονόματος")
            dialog.geometry("650x480") # Slightly wider
            dialog.transient(self.root) 
            dialog.grab_set() 
    
            result = {} 
    
            suggested_name_raw = video_info.get('title', 'ertflix_video')
            suggested_name = re.sub(r'[\\/*?:"<>|]', "", suggested_name_raw)[:150] # Limit length
            
            ttk.Label(dialog, text="Όνομα Αρχείου:").grid(row=0, column=0, padx=5, pady=5, sticky="w")
            name_entry = ttk.Entry(dialog, width=70) # Wider
            name_entry.insert(0, suggested_name)
            name_entry.grid(row=0, column=1, columnspan=2, padx=5, pady=5, sticky="ew")
    
            ttk.Label(dialog, text="Ποιότητα Βίντεο:").grid(row=1, column=0, padx=5, pady=5, sticky="w")
            video_formats_combo = ttk.Combobox(dialog, width=67, state="readonly") # Wider
            video_formats_combo.grid(row=1, column=1, columnspan=2, padx=5, pady=5, sticky="ew")
            
            video_options = []
            video_map = {} 
            
            default_video_selection = None
            highest_res_so_far = 0
    
            for fmt in video_info.get('formats', []):
                if fmt.get('vcodec') != 'none' and fmt.get('vcodec') != 'unknown_video' and fmt.get('acodec') == 'none': 
                    res = fmt.get('height', 0)
                    if not isinstance(res, int): res = 0 # Ensure res is int
                    
                    fps_str = f"@{int(fmt['fps'])}fps" if fmt.get('fps') and isinstance(fmt['fps'], (int, float)) else ""
                    vbr_str = f"~{int(fmt['vbr'])}k" if fmt.get('vbr') and isinstance(fmt['vbr'], (int, float)) else ""
                    ext = fmt.get('ext', 'N/A')
                    format_note = f" ({fmt.get('format_note', '')})" if fmt.get('format_note') else ""
                    
                    display = f"{fmt.get('format_id')} - {res}p{fps_str}{format_note} ({fmt.get('vcodec','N/A')}, {ext}, {vbr_str})"
                    video_options.append(display)
                    video_map[display] = fmt['format_id']
    
                    # Logic for default selection (best or last used)
                    if self.last_video_quality_id == fmt['format_id']:
                        default_video_selection = display
                    elif default_video_selection is None and res > highest_res_so_far: # Basic "best"
                        highest_res_so_far = res
                        default_video_selection = display
    
            video_formats_combo['values'] = sorted(video_options, key=lambda x: int(re.search(r'- (\d+)p', x).group(1)) if re.search(r'- (\d+)p', x) else 0, reverse=True) # Sort by resolution
            
            if default_video_selection and default_video_selection in video_formats_combo['values']:
                video_formats_combo.set(default_video_selection)
            elif video_formats_combo['values']:
                 video_formats_combo.current(0) 
    
            ttk.Label(dialog, text="Ποιότητα Ήχου:").grid(row=2, column=0, padx=5, pady=5, sticky="w")
            audio_formats_combo = ttk.Combobox(dialog, width=67, state="readonly") # Wider
            audio_formats_combo.grid(row=2, column=1, columnspan=2, padx=5, pady=5, sticky="ew")
    
            audio_options = []
            audio_map = {} 
            default_audio_selection = None
            highest_abr_so_far = 0
    
            for fmt in video_info.get('formats', []):
                if fmt.get('acodec') != 'none' and fmt.get('acodec') != 'unknown_audio' and fmt.get('vcodec') == 'none': 
                    abr = fmt.get('abr', 0)
                    if not isinstance(abr, (int,float)): abr = 0 # Ensure abr is numeric
                    
                    ext = fmt.get('ext', 'N/A')
                    display = f"{fmt.get('format_id')} - {int(abr)}k ({fmt.get('acodec', 'N/A')}, {ext})"
                    audio_options.append(display)
                    audio_map[display] = fmt['format_id']
    
                    if self.last_audio_quality_id == fmt['format_id']:
                        default_audio_selection = display
                    elif default_audio_selection is None and abr > highest_abr_so_far: # Basic "best"
                        highest_abr_so_far = abr
                        default_audio_selection = display
    
            audio_formats_combo['values'] = sorted(audio_options, key=lambda x: int(re.search(r'- (\d+)k', x).group(1)) if re.search(r'- (\d+)k', x) else 0, reverse=True) # Sort by bitrate
    
            if default_audio_selection and default_audio_selection in audio_formats_combo['values']:
                audio_formats_combo.set(default_audio_selection)
            elif audio_formats_combo['values']:
                audio_formats_combo.current(0)
    
            ttk.Label(dialog, text="Φάκελος Αποθήκευσης:").grid(row=3, column=0, padx=5, pady=5, sticky="w")
            path_entry = ttk.Entry(dialog, width=60) # Wider
            path_entry.insert(0, self.last_save_directory)
            path_entry.grid(row=3, column=1, padx=5, pady=5, sticky="ew")
            
            def browse_path():
                directory = filedialog.askdirectory(initialdir=path_entry.get() or self.last_save_directory, title="Επιλογή Φακέλου Αποθήκευσης")
                if directory:
                    path_entry.delete(0, tk.END)
                    path_entry.insert(0, directory)
            
            browse_button = ttk.Button(dialog, text="...", command=browse_path, width=3)
            browse_button.grid(row=3, column=2, padx=5, pady=5, sticky="w")
            
            dialog.grid_columnconfigure(1, weight=1) 
    
            button_frame = ttk.Frame(dialog)
            button_frame.grid(row=4, column=0, columnspan=3, pady=10)
    
            def on_ok():
                if not name_entry.get().strip():
                    messagebox.showerror("Λείπει Όνομα", "Το όνομα αρχείου δεν μπορεί να είναι κενό.", parent=dialog)
                    return
                if not video_formats_combo.get() or not audio_formats_combo.get():
                     messagebox.showerror("Λείπει Επιλογή", "Πρέπει να επιλέξετε ποιότητα βίντεο και ήχου.", parent=dialog)
                     return
                if not path_entry.get().strip() or not os.path.isdir(path_entry.get().strip()):
                    messagebox.showerror("Λάθος Φάκελος", "Ο φάκελος αποθήκευσης δεν είναι έγκυρος.", parent=dialog)
                    return
    
                result["name"] = name_entry.get().strip()
                result["video_id"] = video_map.get(video_formats_combo.get()) # Use .get() for safety
                result["audio_id"] = audio_map.get(audio_formats_combo.get()) # Use .get() for safety
                result["path"] = path_entry.get().strip()
                
                if not result["video_id"] or not result["audio_id"]:
                    messagebox.showerror("Σφάλμα Επιλογής", "Προέκυψε σφάλμα με την επιλογή μορφής. Δοκιμάστε ξανά.", parent=dialog)
                    return
    
                dialog.destroy()
    
            def on_cancel():
                dialog.destroy()
    
            ok_button = ttk.Button(button_frame, text="OK", command=on_ok)
            ok_button.pack(side=tk.LEFT, padx=10)
            cancel_button = ttk.Button(button_frame, text="Άκυρο", command=on_cancel)
            cancel_button.pack(side=tk.LEFT, padx=10)
            
            dialog.protocol("WM_DELETE_WINDOW", on_cancel) 
            self.root.wait_window(dialog) 
            return result
    
    
    if __name__ == "__main__":
        if not os.path.exists(YT_DLP_PATH):
            import shutil
            if shutil.which("yt-dlp") or shutil.which("yt-dlp.exe"):
                 YT_DLP_PATH = "yt-dlp" 
            else:
                root_check = tk.Tk()
                root_check.withdraw() 
                messagebox.showerror("Σφάλμα Κρίσιμο", f"Το {YT_DLP_PATH} δεν βρέθηκε!\nΠαρακαλώ τοποθετήστε το yt-dlp.exe στον ίδιο φάκελο με την εφαρμογή ή προσθέστε το στο PATH του συστήματος.")
                root_check.destroy()
                exit(1)
                
        root = tk.Tk()
        app = ErtflixDownloaderApp(root)
        root.mainloop()
    ή για ευκολία κατεβάστε το από εδώ

  7. #307
    Εγγραφή
    28-01-2008
    Ηλικία
    53
    Μηνύματα
    2.578
    Downloads
    13
    Uploads
    0
    Τύπος
    VDSL2
    Ταχύτητα
    51200/5120
    ISP
    Vodafone
    Router
    Vodafone H-300s
    Παράθεση Αρχικό μήνυμα από microvio Εμφάνιση μηνυμάτων
    Έτοιμο το πρόγραμμα. Το αρχείο ARRAY_ERTFLIX πάει πλέον στον φάκελο του χρήστη.
    Όποτε εάν υπάρχει φάκελος home/pi κάντε διαγραφή.
    Δοκιμάστε και εάν έχει κάποιο πρόβλημα εδώ είμαστε. Μονό για οποία επίλυση και προσθήκη θα αργήσει λόγο υποχρεώσεων. Το έχω δοκιμάσει, ελεύθερα μπορείτε να κάνετε οποιαδήποτε προσθήκη

    ...
    Δουλεύει μια χαρά τώρα! Να είσαι καλά!

  8. #308
    Εγγραφή
    04-05-2025
    Μηνύματα
    13
    Downloads
    0
    Uploads
    0
    ISP
    Vodafone
    @yyy χαίρομαι να είσαι καί εσύ καλά.

  9. #309
    Εγγραφή
    28-03-2022
    Μηνύματα
    8
    Downloads
    0
    Uploads
    0
    ISP
    Forthnet
    Μηπως υπαρχει m3u8 για το μεγα τσανελ?

Σελ. 21 από 21 ΠρώτηΠρώτη ... 1116192021

Tags για αυτό το Θέμα

Bookmarks

Bookmarks

Δικαιώματα - Επιλογές

  • Δεν μπορείτε να δημοσιεύσετε νέα θέματα
  • Δεν μπορείτε να δημοσιεύσετε νέα μηνύματα
  • Δεν μπορείτε να αναρτήσετε συνημμένα
  • Δεν μπορείτε να επεξεργαστείτε τα μηνύματα σας
  •  
  • Τα BB code είναι σε λειτουργία
  • Τα Smilies είναι σε λειτουργία
  • Το [IMG] είναι σε λειτουργία
  • Το [VIDEO] είναι σε λειτουργία
  • Το HTML είναι εκτός λειτουργίας