1. Java / Говнокод #26836

    +1

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    package com.company;
    
    public class Main {
    
        public static void main(String[] args) {
            int answer = 0;
    
            for (int i = 100; i < 1000; i++){
                for (int j = 100; j < 1000; j++){
                    int result = i * j;
    
                    String str = String.valueOf(result); //convert
                    String revers = new StringBuffer(str).reverse().toString(); //revers
                    int newb = Integer.parseInt(revers); //convert
    
                    if (newb == result){
                        int answer001 = result;
    
    
                        if (answer001 > answer) answer = answer001;
                    }
    
                }
            }
            System.out.println(answer);
    
        }
    
    }

    реализация четвёртой задачки из проекта эйлера

    Запостил: warzon131, 01 Августа 2020

    Комментарии (279) RSS

    • Мощный способ перевернуть цифры в числе, особенно в цикле
      Ответить
      • Вай нот? На эйлере тайминги никто не смотрит, ответ выдал - и ладно.
        Ответить
        • Ну у тебя рука бы поднялась такое написать? В зеркало потом плюнуть не захотелось бы?
          Ответить
          • Вай нот? Просто, наглядно, задачу решает. Я не перфекционист, чтобы одноразовый код выдрачивать до блеска.
            Ответить
            • Я ни разу не перфкц тоже, но так бы не написал
              Лучше уж напитонячить тогда: там это будет не так ужасно
              Ответить
              • Лучше напхпшить, там из-за неявных кастов вообще говна не видно будет.
                Ответить
                • Так и на перле можно, там вообще одни скаляры
                  my $foo = 12345;
                  print reverse split //, $foo;
                  Ответить
              • > Лучше уж напитонячить тогда: там это будет не так ужасно
                Подтверждаю. Не отклоняясь от изначального алгоритма:
                x == int(str(x)[::-1])
                Ответить
                • Вот по какой-то причине на питоне я могу так написать

                  Видимо, внутренний линтер зависит от языка
                  Ответить
                  • А на джаве сразу хочется энтерпрайза и фабрик?
                    Ответить
                    • Хочется сделать массив в памяти, разбить число на цифры с помощью оператора % 1[многонолей], заполнить этот массив, потом собрать число обратно с помощью умножения и сложения, и таким образом его перевернуть?
                      Ответить
                      • > собрать число обратно

                        Зачем? Зачем? В общем-то и в версии ОПа можно было остановиться на str == revers.
                        Ответить
                        • даже так

                          В общем, создавать буферы в цикле бы точно не хотелось
                          Ответить
                          • Да там вообще массив не нужен, см. решение Госта.
                            Ответить
                            • да, он вместо массива использует собссно число
                              Ответить
                • x == strrev(x)

                  Именно поэтому я за пхп.

                  P.S. И ведь хрен ты придумаешь более красивое и наглядное решение.
                  Ответить
              • Ну, если бы здесь всё было бы идеально, то и на этом сайте не было бы пополнения
                Ответить
              • Наивный питон, проверь:
                def reverse_num(x):
                    x_reverse = 0
                    while x > 0:
                        x_reverse *= 10
                        x_reverse += x % 10
                        x //= 10
                    return x_reverse
                
                
                def mults(start, end, step):
                    for i in range(start, end, step):
                        for j in range(i, end, step):
                            if (x := i*j) == reverse_num(x):
                                yield x
                
                
                max(mults(999, 99, -1))  # 906609 == 913*993

                Можно оптимизировать (например, прекращать вычисления, когда оба множителя меньше наименьшего из предыдущей найденной пары), но мне лень.
                Ответить
                • Сишник на любом языке пишет как на си.
                  Ответить
                  • показать все, что скрытоvanished
                    Ответить
                    • Да я не вижу там особого ужаса. Зачем заниматься преждевременной оптимизацией и вручную числа пердолить если есть готовое преобразование в строку?
                      Ответить
                      • Сложно объяснить. У меня даже и мысли бы не родилось переворачивать число через строку, тем более на джаве, где есть нормальный int, а ты бы так и написал?
                        Ответить
                        • Если ограничений на пирфоманс нету - наверное да. Читается же лучше чем ручной пердолинг с цифрами.
                          Ответить
                • > if (x := i*j) == reverse_num(x):

                  Побочные эффекты посреди выражений!? Бля, это серьёзно завезли в питон? ЗАЧЕМ? ЗАЧЕМ?
                  Ответить
                • А теперь самое смешное:
                  def reverse_num_tsar(x):
                      x_reverse = 0
                      while x > 0:
                          x_reverse *= 10
                          x_reverse += x % 10
                          x //= 10
                      return x_reverse
                  
                  
                  def reverse_num_unskill(x):
                      return int(str(x)[::-1])
                  
                  
                  def mults_tsar(start, end, step):
                      for i in range(start, end, step):
                          for j in range(i, end, step):
                              if (x := i*j) == reverse_num_tsar(x):
                                  yield x
                  
                  
                  def mults_unskill(start, end, step):
                      for i in range(start, end, step):
                          for j in range(i, end, step):
                              if (x := i*j) == reverse_num_unskill(x):
                                  yield x
                  
                  
                  print(timeit.timeit('max(mults_tsar(999, 99, -1))', globals=globals(), number=10))     # 3.716285999980755 секунд
                  print(timeit.timeit('max(mults_unskill(999, 99, -1))', globals=globals(), number=10))  # 1.8206677000271156 секунд


                  Какой анскилл (((
                  Ответить
                  • показать все, что скрытоvanished
                    Ответить
                    • Профайлинг ничего не говорит, только то, что царский реверс медленнее. Дизасм показывает более подробно:
                      >>> dis.dis(reverse_num_tsar)
                        2           0 LOAD_CONST               1 (0)
                                    2 STORE_FAST               1 (x_reverse)
                      
                        3     >>    4 LOAD_FAST                0 (x)
                                    6 LOAD_CONST               1 (0)
                                    8 COMPARE_OP               4 (>)
                                   10 POP_JUMP_IF_FALSE       42
                      
                        4          12 LOAD_FAST                1 (x_reverse)
                                   14 LOAD_CONST               2 (10)
                                   16 INPLACE_MULTIPLY
                                   18 STORE_FAST               1 (x_reverse)
                      
                        5          20 LOAD_FAST                1 (x_reverse)
                                   22 LOAD_FAST                0 (x)
                                   24 LOAD_CONST               2 (10)
                                   26 BINARY_MODULO
                                   28 INPLACE_ADD
                                   30 STORE_FAST               1 (x_reverse)
                      
                        6          32 LOAD_FAST                0 (x)
                                   34 LOAD_CONST               2 (10)
                                   36 INPLACE_FLOOR_DIVIDE
                                   38 STORE_FAST               0 (x)
                                   40 JUMP_ABSOLUTE            4
                      
                        7     >>   42 LOAD_FAST                1 (x_reverse)
                                   44 RETURN_VALUE
                      >>> dis.dis(reverse_num_unskill)
                        2           0 LOAD_GLOBAL              0 (int)
                                    2 LOAD_GLOBAL              1 (str)
                                    4 LOAD_FAST                0 (x)
                                    6 CALL_FUNCTION            1
                                    8 LOAD_CONST               0 (None)
                                   10 LOAD_CONST               0 (None)
                                   12 LOAD_CONST               1 (-1)
                                   14 BUILD_SLICE              3
                                   16 BINARY_SUBSCR
                                   18 CALL_FUNCTION            1
                                   20 RETURN_VALUE

                      Царская функция дробит числа, а как числодробилка нативный «Питон» работает до крайности хуёво.
                      Ответить
                      • Причём на больших числах дробление на нативном «Питоне» начинает сливать совершенно безбожно:
                        >>> timeit.timeit('reverse_num_tsar(999999)', globals=globals())
                        0.9148282000096515
                        >>> timeit.timeit('reverse_num_unskill(999999)', globals=globals())
                        0.40631799993570894
                        # Медленнее в 2.25 раз
                        
                        >>> timeit.timeit('reverse_num_tsar(9999999999999999999999999999999999999)', globals=globals())
                        7.19681880006101
                        >>> timeit.timeit('reverse_num_unskill(9999999999999999999999999999999999999)', globals=globals())
                        0.5664128999924287
                        # Медленнее в 12.7 раз
                        
                        >>> timeit.timeit('reverse_num_tsar(99999999999999999999999999999999999999999999999999999999999999999999999999)', globals=globals())
                        16.09511850005947
                        >>> timeit.timeit('reverse_num_unskill(99999999999999999999999999999999999999999999999999999999999999999999999999)', globals=globals())
                        0.780789399985224
                        # Медленнее в 20.61 раз
                        Ответить
                        • Ну вот потому на скриптушке так делать и нормально)
                          Ответить
                        • На крестах, разумеется, царская версия уделывает анскильную в ~4.6 раз: https://quick-bench.com/q/KAIwyYsAwIIBC_EWhyc6X8bOX78.
                          Ответить
                          • говно ваш питон

                            На жабе троже
                            public class Main {
                            
                                public static void main(String[] args) {
                                    int answer = 0;
                                    long now = System.currentTimeMillis();
                            
                                    for (int i = 100; i < 1000; i++) {
                                        for (int j = 100; j < 1000; j++) {
                                            int result = i * j;
                            
                                            int newb = reverseLikeTsar(result);
                                            
                                            // Use reverseLikeUnskilledPetuz to test ptih
                            
                                            if (newb == result) {
                                                int answer001 = result;
                            
                            
                                                if (answer001 > answer) answer = answer001;
                                            }
                            
                                        }
                                    }
                                    System.out.println(answer);
                                    System.out.println(System.currentTimeMillis() - now); //unskilled: 120, tsar: 17
                            
                                }
                            
                                private static int reverseLikeUnskilledPetuz(int toReverse) {
                                    String str = String.valueOf(toReverse); //convert
                                    String revers = new StringBuffer(str).reverse().toString(); //revers
                                    return Integer.parseInt(revers);
                                }
                            
                                private static int reverseLikeTsar(int toReverse) {
                                    int result = 0;
                                    while (toReverse > 0) {
                                        result *= 10;
                                        result += toReverse % 10;
                                        toReverse /= 10;
                                    }
                                    return result;
                                }
                            
                            }


                            В 10 раз, в 10 блядь раз
                            Ответить
                            • > В 10 раз

                              С учётом прибавления и отнимания '0' и трёх аллокаций выглядит совсем неплохо. Я думал хуже будет.
                              Ответить
                              • Нужно уменьшить xmx и спровоцировать GC. Тогда аллокации станут еще дороже.

                                Но в кучу анскильный вариант срёт знатно, конечно
                                Зацени
                                https://postimg.cc/xXQynRK5
                                Ответить
                                • Да не будут они дороже. Эти буфера очень мало живут, их в последующие поколения даже не копируют. Поэтому хоть аллокаций и дохуя но они шустрые, по сути за О(1).
                                  Ответить
                                  • показать все, что скрытоvanished
                                    Ответить
                                    • а вот нормально, что я уже давно перестал понимать, что вы здесь пишите?
                                      Ответить
                                    • Дык удаление в копирующем гц как раз таки бесплатное, в отличие от сишки.

                                      Ты платишь фиксированную цену за запуск гц и обход стека каждые N мегабайт. Но мертвые объекты же недостижимы, их двигать не надо.

                                      На мелких временных аллокациях джава в клочья сишку порвёт, имхо. Если сишник не будет читерить с переменными на стеке, конечно.
                                      Ответить
                                      • показать все, что скрытоvanished
                                        Ответить
                                      • > На мелких временных аллокациях джава в клочья сишку порвёт, имхо.
                                        Хуета.
                                        Полная хуета.

                                        >Если сишник не будет читерить с переменными на стеке, конечно.

                                        Царь даже без стека эту хуйню сольёт.
                                        Если я хуйну SLAB-аллокацию или заранее выделю себе mmapом мегабайты памяти, как это делает Йажа, то она опять сольётся в хламину.

                                        Йажа-сектанты часто пишут бенчи в стиле: Сишные malloc+free vs преаллоциорованный гиг памяти в Йажа, причём бенчмарк заканчивается ещё до первой сборки. См. -Xmx 1Gb

                                        После чего делаются многозначительные выводы и пишутся статьи для хабархабра: «Придуман новый язык, быстрее чем Си».
                                        Ответить
                                        • показать все, что скрытоvanished
                                          Ответить
                                          • > в .NET можно хранить объекты на стеке, а в JVM -- нет
                                            Инты в ЙАЖЕ как раз хранятся на стеке, если их в коробки не завернули. В отличие от «Python», в котором каждая арифметическая операция — это создание нового объекта с соответствующим дёрганьем кучи. Собственно, почему он так и тормозит на царском алгоритме.
                                            Ответить
                                            • показать все, что скрытоvanished
                                              Ответить
                                              • > А там нету пула для литералов чисел кстати, как в йаже?
                                                Есть, до 255-и, кажется. Или поменьше, не помню.
                                                Ответить
                                                • показать все, что скрытоvanished
                                                  Ответить
                                                  • Хз, особенности ГЦ, наверное. Типа надо чтобы все объекты были PyObject и в куче, иначе рахитектура разваливается.
                                                    Ответить
                                                    • показать все, что скрытоvanished
                                                      Ответить
                                                      • Какой ООП )))
                                                        Ответить
                                                        • показать все, что скрытоvanished
                                                          Ответить
                                                          • > Ты юзал какие-нить продвинутые средства профилирования кроме timeit и cprofile?
                                                            Нет, необходимости не было.
                                                            Ответить
                                                            • показать все, что скрытоvanished
                                                              Ответить
                                                              • Ну да, какой в «Питоне» перформанс? Стандартный способ борьбы с тормозами в «Питоне»: либо выкинуть «Питон» и всё перевести на сишку, либо перевести на сишку только тормозящий мудуль.

                                                                А ещё к «Питону» можно прикрутить «JIT»: https://numba.pydata.org/. Говорят, помогает.
                                                                Ответить
                                                                • показать все, что скрытоvanished
                                                                  Ответить
                                                                  • Не, «Cython» только смотрел, и то издали.
                                                                    Ответить
                                                                • Проверил «JIT», работает.
                                                                  from numba import jit
                                                                  
                                                                  
                                                                  @jit(nopython=True)
                                                                  def mults(start, end, step):
                                                                      min_i = min(start, end)
                                                                      for i in range(start, end, step):
                                                                          if i < min_i:
                                                                              return
                                                                          for j in range(i, end, step):
                                                                              x = i * j
                                                                              x_orig = x
                                                                              x_reverse = 0
                                                                              while x > 0:
                                                                                  x_reverse *= 10
                                                                                  x_reverse += x % 10
                                                                                  x //= 10
                                                                              if x_orig == x_reverse:
                                                                                  min_i = max(min_i, j)
                                                                                  yield x_orig
                                                                                  break
                                                                  
                                                                  
                                                                  print(timeit.timeit('max(mults(999, 99, -1))', globals=globals(), number=100))
                                                                  # 0.1662201 секунд первый запуск, 0.0333973 последующие

                                                                  В 8.7 раз быстрее максимально ускоренной анскильной (см. ниже) на первом запуске, в 43 раза быстрее на последующих.
                                                                  Ответить
                                                                  • function* mults(start, end) {
                                                                        let min_i = end;
                                                                        for (let i = start; i > end; i--) {
                                                                            if (i < min_i) {
                                                                                return;
                                                                            }
                                                                            for (let j = i; j > end; j--) {
                                                                                let x = i * j;
                                                                                let x_orig = x;
                                                                                let x_reverse = 0;
                                                                                while (x > 0) {
                                                                                    x_reverse *= 10;
                                                                                    x_reverse += x % 10;
                                                                                    x =~~ (x / 10);
                                                                                }
                                                                                if (x_orig == x_reverse) {
                                                                                    min_i = Math.max(min_i, j);
                                                                                    yield x_orig;
                                                                                    break;
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                    
                                                                    function get_palindrom(start, end) {
                                                                        let max_x = 0;
                                                                        for (const x of mults(start, end)) {
                                                                            max_x = Math.max(max_x, x);
                                                                        }
                                                                        return max_x;
                                                                    }
                                                                    
                                                                    console.time('get_palindrom');
                                                                    for (let i = 0; i < 100; i++) {
                                                                        get_palindrom(999, 99);
                                                                    }
                                                                    console.timeEnd('get_palindrom');  // get_palindrom: 80.52001953125ms

                                                                    Бамп отсосу «JavaScript»!
                                                                    Ответить
                  • str и int поди на сишке выдрочены, поэтому быстрее чем цикл на самом питоне.

                    Вот тебе и преждевременная оптимизация.
                    Ответить
                  • Оптимизировал анскильную версию в >2 раза:
                    def mults(start, end, step):
                        for i in range(start, end, step):
                            for j in range(i, end, step):
                                x = i * j
                                x_str = str(x)
                                if x_str == x_str[::-1]:
                                    yield x
                                    break
                    
                    
                    print(timeit.timeit('max(mults(999, 99, -1))', globals=globals(), number=10))  # 0.8841240999754518 секунд
                    Ответить
                    • Оптимизировал ещё в 6 раз:
                      def mults(start, end, step):
                          min_i = min(start, end)
                          for i in range(start, end, step):
                              if i < min_i:
                                  return
                              for j in range(i, end, step):
                                  x = i * j
                                  x_str = str(x)
                                  if x_str == x_str[::-1]:
                                      # Нашли очередной палиндром x = i * j;
                                      # Палиндромы с i меньше текущего j проверять не имеет смысла:
                                      # они гарантированно меньше найденного
                                      min_i = max(min_i, j)
                                      yield x
                                      break
                      
                      
                      # N.B.: в 10 раз больше, чем в предыдущих вореантах
                      print(timeit.timeit('max(mults(999, 99, -1))', globals=globals(), number=100))  # 1.45771029999014 секунд
                      Ответить
                  • Ничего удивительного.

                    Слайсы ебошит нативная сишка. А деления анскильный Питух.

                    Лалки обсирали jsую идиому str.split('').reverse().join('')

                    Однако же:
                    str.split('') //по сути взятие низлежащего массива
                    tempArr0.reverse() //нативный реверс
                    tempArr1.reverse() //сделай мне на массиве строку
                    Ответить
                    • показать все, что скрытоvanished
                      Ответить
                    • - tempArr1.reverse() //сделай мне на массиве строку
                      + tempArr1.join('') //сделай мне на массиве строку
                      fix

                      Я к тому что этот метод довольно долгое время был самым быстрым.
                      Похоже в браузерах пустые сплиты/джойны шли по отдельному оптимизированному пути.
                      Ответить
          • На самом деле, я на эйлере часто закидывал наивное говно просто чтобы почитать как другие чуваки применяют какой-нибудь гениальный матан и решают за О(1).

            Я вот думаю они и тут без перебора решили.
            Ответить
            • показать все, что скрытоvanished
              Ответить
              • { Вы | случайно ≠ ма-те-ма-тик ? }
                Ответить
                • показать все, что скрытоvanished
                  Ответить
                  • Генеришь 5-6 значные палиндромы, их меньше тысячи, факторизуешь их начиная с самого большого и смотришь можно ли склеить множители в группы меньше 1000.
                    Ответить
                    • Борманд, а тебе было бы заниматься разработкой чего-то типа Твитча?
                      Ответить
                      • Да не особо. Что там интересного? Вебморда да тупейшие ретрансляторы. Он ведь даже не обрабатывает поток вроде, вся тяжёлая работа на компе стримера.
                        Ответить
                        • Так я про бэк и не говорю.

                          Я про софт, который у стримера стоит. Захват видео, кодирование, передача.

                          Типа хуета это всё?
                          Ответить
                          • > Я про софт, который у стримера стоит.
                            Дык что его разрабатывать, он уже в опенсорсе есть: https://github.com/obsproject/obs-studio.
                            Ответить
                            • У твитча нет своего клиента в смысле?

                              Какой высокотехнологичный стартап )))
                              Ответить
                              • Эм, а зачем им свой клиент? Есть платный xsplit, есть бесплатный obs. Можешь ими хоть на твич, хоть на ютуб хоть в порночатики стримить. Нахуй плодить сущности?
                                Ответить
                                • Спасибо, я не знал. Думал, что они что-то своё запилили. Тогда там реально основная работа это балансировка.

                                  > Нахуй плодить сущности?
                                  - как будто ты не знаешь про nih
                                  Ответить
                                  • > - как будто ты не знаешь про nih
                                    А это будет тяжелейшим выстрелом в ногу. Абсолютное большинство крупных стримеров (т.е. все те, кто приносят «Твичу» бабло) стримят не напрямую, а через что-то типа https://restream.io/ — штуковины, которая размножает поток на несколько платформ с опциональным добавлением всяких межплатформенных фишек. И работает это потому, что протоколы для стриминга открыты и стандартизованы.
                                    Ответить
                              • Ну да, а зачем он* ему нужен? «OBS» может по простым стандартизированным протоколам стримить хоть на «Твич», хоть на «Ютуб», хоть чёрту в ступу. Проприетарное пятое колесо никому нахуй не нужно.

                                *Клиент у «Твича», на самом деле, имеется, но он нужен только для просмотра каналов и сбора дополнительных данных пользователей.
                                Ответить
                          • Х.з., я не вижу смысла делать ещё одно проприетарное говнище, разве что в OBS поконтрибьютить.
                            Ответить
                          • >Я про софт, который у стримера стоит. Захват видео, кодирование, передача.

                            Бууэээ. На курятнике писать энкодер для AV1. Твич поставил на rav1e.

                            https://github.com/xiph/rav1e

                            Который наглухо сливает всем сишноплюсовым (aom, SVT-AV1) конкурентам и по скорости и по зожатию.
                            При том что по времени они все начали писать их примерно одновременно.
                            Ответить
                            • Еле догадался, что курятник это Rust. (По ссылке не ходил)
                              Ответить
                        • Не, поток там, ЕМНИП, ужимается в несколько потоков поменьше (ну как в «Ютубе» качество можно выбирать).
                          Хотя я не уверен, возможно, и это тоже должно быть на компе сделано.

                          ИМХО, самое интересное там — это сетевая рахитектура, которая должна раскидывать гигантское количество трафика с минимальными задержками (2 секунды отставания от стримера, например).
                          Ответить
                          • > ужимается

                            Я могу ошибаться, но по-моему low-res потоки тоже на компе стримера создаются. Ща проверю.

                            > сетевая рахитектура

                            Я не думаю, что там прям что-то гениальное... Скорее всего обычное дерево с датацентром в каждом регионе.

                            А на задержку там всем похуй на самом деле, ну ответит тебе стример на 5 секунд позже, не помрёшь.
                            Ответить
                            • показать все, что скрытоvanished
                              Ответить
                              • Ой да не факт. Гигабит ты без проблем высрешь, это же поток а не пинг-понг.
                                Ответить
                                • показать все, что скрытоvanished
                                  Ответить
                                  • Бгг, бывает до первого пирфоманс-инженера
                                    Ответить
                                  • Чанки по HTTPS вроде.
                                    Ответить
                                    • показать все, что скрытоvanished
                                      Ответить
                                      • Чанки по хттпс это практически наверняка мпег-даш. Задержка секунд 15.
                                        Для ~ реалтайма надо тащить вебсокет/вебртц
                                        Ответить
                                        • показать все, что скрытоvanished
                                          Ответить
                                          • Этим «вебсокеты» сами занимаются. Клиент просто открывает TCP-соединение с сервером, и уже по нему данные туда-сюда спокойно гоняются.
                                            Ответить
                                            • показать все, что скрытоvanished
                                              Ответить
                                              • > Если я за натом, и ты за натом, то мне трудно показать тебе видео не через сервер.
                                                Стримить не через сервер вообще сложновато. Ты что, предлагаешь стримеру отправлять копию видеопотока десятку-другому тысяч зрителей напрямую?
                                                Ответить
                                              • > показать тебе видео

                                                Ну мы же сейчас не про скайп, а про раздачу потока тысячам зрителей. Никто в здравом уме там не будет напрямую коннектица, у стримера комп и без этого перегружен.
                                                Ответить
                                                • показать все, что скрытоvanished
                                                  Ответить
                                                  • > Зачем TCP видеостриму?

                                                    Х.з., исторически сложилось. Там же "протокол" у этих DASH и HLS - это тупо плейлист из чанков. Можешь закинуть их на сервер статикой и смотреть. Можешь в реалтайме отдавать.
                                                    Ответить
                                                    • показать все, что скрытоvanished
                                                      Ответить
                                                      • Если TCP на своём уровне не успеет вовремя перепослать потерянный пакет, то чанк тупо дропнется и в видео будет дыра и надпись "buffering".
                                                        Ответить
                                                        • показать все, что скрытоvanished
                                                          Ответить
                                                          • Тем что на хуёвом канале браузер поднимает буфер до упора и ты с лагом в минуту но таки можешь смотреть видос без выпадания кадров.
                                                            Ответить
                                                            • показать все, что скрытоvanished
                                                              Ответить
                                                              • А эти кадры ещё не старые, они только выстраиваются в очередь к показу. И если ты успеваешь их выкачать со второй-третьей попытки - юзер вообще никаких проблем не заметит. Чем больше буфер - тем больше шансов что всё будет выкачано к дедлайну.
                                                                Ответить
                                                                • показать все, что скрытоvanished
                                                                  Ответить
                                                                  • > А если я пишу "чувак, что ты делаешь?!", а он уже давно этот уровень прошел, разве это не багор?>
                                                                    Ну если ты готов терпеть постоянно рассыпающийся видеопоток ради снижения задержки на десяток-другой секунд…
                                                                    Ответить
                                                                    • показать все, что скрытоvanished
                                                                      Ответить
                                                                      • Вряд ли навсегда, скорее там в какой-то момент произойдёт синк и ты всё равно проебёшь часть видео. Зато догонишь
                                                                        Ответить
                                                                        • В «Твиче» синк происходит то ли после минутного буфера, то ли вообще после двухминутного. Если у тебя канал настолько плох — через «UDP» ты вообще ничего не увидишь.
                                                                          Ответить
                                                                          • Ну Твич Твичем, а на всяких alliez.tv или как он там это обычная картина.
                                                                            Ответить
                                                                        • >Вряд ли навсегда, скорее там в какой-то момент произойдёт синк и ты всё равно проебёшь

                                                                          А, пацаны. Это хуйня всё. Вы не шарите. Эти проблемы давным-давно решены несколькими различными способами.

                                                                          Почитайте про intra-refresh. Он волной макроблоки обновляет. Был ещё в x264.

                                                                          Periodic Intra Refresh instead of keyframes, which enables each frame to be capped to the same size enabling each slice to be immediately transmitted in a single UDP or TCP packet and on arrival immediately decoded.

                                                                          Periodic Intra Refresh can replace keyframes by using a column of intra blocks that move across the video from one side to the other, thereby "refreshing" the image. In effect, instead of a big keyframe, the keyframe is "spread" over many frames. The video is still seekable: a special header, called the SEI Recovery Point, tells the decoder to "start here, decode X frames, and then start displaying the video." This hides the refresh effect from the user while the frame loads. Motion vectors are restricted so that blocks on one side of the refresh column don't reference blocks on the other side, effectively creating a demarcation line in each frame.
                                                                          Ответить
                                                                          • показать все, что скрытоvanished
                                                                            Ответить
                                                                            • Видимо, похерится только часть кадра. Лицо будет видно, а сиськи уже нет
                                                                              Ответить
                                                                            • >Так а что будет, если я проебу часть?
                                                                              Может пара кадров проебаться, но буфер весьма быстро восстановится.

                                                                              Вертикальная полоска за 5-10 кадров сделает полный self-refresh. И не надо ждать I-frame.

                                                                              Ценой этого чуть более низкое зожатие.

                                                                              Смысл в том, что в P-кадре или B-кадре могут быть I-блоки, которые ни от чего не зависят.
                                                                              Ответить
                                                                              • Ну это скорее для телеков и видеочатов в реалтайме, чем для стримов?
                                                                                Ответить
                                                                      • > Да почему постоянно?
                                                                        Потому что так потери пакетов работают. У тебя просто постоянно теряется N процентов пакетов.

                                                                        > У меня помеха пошла по docsis на N ms.
                                                                        При чём тут «DOCSIS»-то? Мы про «Ethernet» говорим.

                                                                        > а в TCP я тупо отстал навсегда, хоть и не потерял кадр
                                                                        Да, при этом чем больше отставание — тем меньше вероятности, что следующие потери истощат буфер.

                                                                        > Оно того стоит?
                                                                        В массовом сегменте — да.
                                                                        Ответить
                                                                        • показать все, что скрытоvanished
                                                                          Ответить
                                                                          • > Совершенно нет.
                                                                            Совершенно да.

                                                                            > Если у меня временные проблемы, то почему они должны быть всегда?
                                                                            Это не временные трудности, это постоянные проблемы. В обычном интернете у тебя всегда теряется какая-то часть пакетов, иногда больше, иногда меньше.

                                                                            > Интернету же пофиг, поврех чего работать.
                                                                            Интернету пофиг, но сейчас он работает поверх «Ethernet» и оптики. Или ты предлагаешь все кабели в Интернете поменять?

                                                                            > если мне нормально отстать на три секунды, но при этом НЕ потерять ни одного видеокадра
                                                                            Да. Смотреть видео с постоянными перерывами — это пиздец как раздражает, пользователи этим заниматься не будут.
                                                                            Ответить
                                                                            • показать все, что скрытоvanished
                                                                              Ответить
                                                                              • > потеря пакета может быть временным явлением

                                                                                А может быть и не временным. Заранее ты не угадаешь. Но один артефакт/буферинг зритель потерпит. На втором начнёт плеваться и уйдёт на другой сервис у которого с задержкой но стабильно.

                                                                                И ты не объяснишь человеку, что это его личная проблема с интернетом. Другие сервисы же нормально идут, лол.
                                                                                Ответить
                                                                                • Пользователь очень сильно смотрит на контент и его количество.

                                                                                  В своё время ЮТуб был диким тормозом, но народ на какой-нибудь Vimeo массово не побежал.

                                                                                  Вопрос в контенте и позиционировании. А стандарты качества у массового пользователя упали, к сожалению
                                                                                  Ответить
                                                                                • показать все, что скрытоvanished
                                                                                  Ответить
                                                                                  • > Если у меня всегда проебывается половина пакетов -- я звоню провайдеру
                                                                                    Для любования на квадраты через «UDP» тебе не нужна потеря половины пакетов, тебе достаточно терять сотые/тысячные доли процента. А это — вполне нормальный режим работы Интернета.
                                                                                    Ответить
                                                                                    • > вполне нормальный режим работы Интернета

                                                                                      Особенно если рядом торрент качается, лол.
                                                                                      Ответить
                                                                                  • Кстати, я недавно жил с 1% потерь и вообще не замечал их. Потоковое видео шло без проблем. В браузере странички иногда подтупливали но грузились. TCP очень неплохо с этим справляется на самом деле.
                                                                                    Ответить
                                                                                    • Я тебе скажу, что мне в последнее время и с 15 процентами приходится сталкиваться, ничего, почти не мешает. Только иногда запросы тупят, ну и похоже 4-ым Героям это не очень нравится лол
                                                                                      Ответить
                                                                                      • Не ну на 10%+ уже хуёво, DNS часто тупит, сайты которые не в кеше не с первого раза открываются и т.п.

                                                                                        Собственно на 10% я уже позвонил провайдеру.
                                                                                        Ответить
                                                                              • > Что не так?
                                                                                То, потери пакетов в обычном режиме очень небольшие, сотая доля процентов, например. Простым пингом на четыре пакеты ты их, разумеется, не увидишь.

                                                                                Типичный стрим — это постоянный видеопоток примерно на 5 мегабайт в секунду полезных данных (40 мегабит). Путём несложных грубых вычислений можно убедиться, что 5 мегабайт в секунду с MSS 1400 — это как минимум 5* 1024**2 // 1400 = 3744 IP-пакета в секунду. То есть, если у тебя теряется 0.003% (три тысячных доли процента) пакетов, то наблюдать квадратики ты будешь раз в десять секунд. Через «TCP», в свою очередь, ты таких потерь в принципе не заметишь.

                                                                                > Да ну? А поверх 11n он не работает, когда ты внутри ESS переключился на другую станцию, и в этот момент проебал пакет?
                                                                                Я вообще-то про магистрали, но да ладно, похуй.
                                                                                Ответить
                                                                                • показать все, что скрытоvanished
                                                                                  Ответить
                                                                                  • > Я не уверен, что замечу квадратики в одном кадре раз в десять секунд
                                                                                    Ну что ж такое, мы же это уже выяснили.
                                                                                    >>> Таким образом, я сосу болта до следующего ключевого кадра, верно?
                                                                                    Ты будешь смотреть на квадратики по одной-двум секундам раз в десять секунд (я — на квадратики по одной-двум секундам раз в пол-секунды, ага).

                                                                                    > Разве пользователь сидит не дома?
                                                                                    Потому что пакеты теряются далеко не только на линии между пользователем и оборудованием провайдера. Они теряются на всём пути от сервера «Твича» и до компьютера пользователя.
                                                                                    Ответить
                                                                                    • показать все, что скрытоvanished
                                                                                      Ответить
                                                                                      • Ну ты мелкой хуйнёй пингуешь. У меня на мелких пакетах тоже всё норм было, а большие пидорасило пока не пришли чуваки и кабель не поменяли.
                                                                                        Ответить
                                                                                      • > "сосу болта" означает "софт не будет иметь информации для отображения", это совсем не значит, что я, как пользователь, обращу на это внимание
                                                                                        Это означает, что пользователь будет смотреть на чёрный квадрат/месиво из квадратиков. Не заметить такое можно только когда ты отвернулся от экрана.

                                                                                        P. S. Минус нечаянно въебал, извини.
                                                                                        Ответить
                                                                                        • Не ну многие стрим держат просто в фоне пока чем-то другим занимаются. Реально могут не заметить.
                                                                                          Ответить
                                                                                          • Ну так тогда увеличившуюся задержку из-за «TCP» они гарантированно не заметят. А вот помехи в звуке могут и услышать.
                                                                                            Ответить
                                                                                • Реальный пример:
                                                                                  # psping.exe -q -i 0 -n 600s ip
                                                                                  
                                                                                  PsPing v2.10 - PsPing - ping, latency, bandwidth measurement utility
                                                                                  Copyright (C) 2012-2016 Mark Russinovich
                                                                                  Sysinternals - www.sysinternals.com
                                                                                  
                                                                                  Pinging ip with 32 bytes of data:
                                                                                  600 seconds (1 warmup pings) connecting test:  57%  Sent = 6293, Received = 6291, Lost = 2 (0% loss),
                                                                                    Minimum = 52.72ms, Maximum = 95.92ms, Average = 53.42ms

                                                                                  Два потерянных пакета на 6293 посланных. То есть, в примере с пятимегабайтным потоком, я буду наблюдать квадратики примерно два раза в секунду.
                                                                                  Ответить
                                                                                  • показать все, что скрытоvanished
                                                                                    Ответить
                                                                                    • показать все, что скрытоvanished
                                                                                      Ответить
                                                                                    • 600 — это слишком мало, это ~160 миллисекунд видеопотока. Пошли хотя бы 10000.
                                                                                      Ответить
                                                                                      • показать все, что скрытоvanished
                                                                                        Ответить
                                                                                        • Добавь тогда ещё -l 1k, чтобы оно килобайт слало.
                                                                                          psping.exe -q -l 1k -i 0 -n 300s IP
                                                                                          
                                                                                          PsPing v2.10 - PsPing - ping, latency, bandwidth measurement utility
                                                                                          Copyright (C) 2012-2016 Mark Russinovich
                                                                                          Sysinternals - www.sysinternals.com
                                                                                          
                                                                                          Pinging IP with 1024 bytes of data:
                                                                                          60 seconds (1 warmup pings) connecting test: 100%
                                                                                          
                                                                                          Ping statistics for IP:
                                                                                            Sent = 666, Received = 661, Lost = 5 (0% loss),
                                                                                            Minimum = 53.37ms, Maximum = 82.76ms, Average = 54.11ms

                                                                                          (Тут я минуту держал вместо пяти)
                                                                                          Ответить
                                                                                      • показать все, что скрытоvanished
                                                                                        Ответить
                                                                                        • > или где-то ошибся?
                                                                                          Ну можно ещё килобатными пакетами попинговать для большего приближения к реальности, ну да это неважно.

                                                                                          > Проеблось 3 пакета из 38164
                                                                                          То есть примерно каждые три секунды ты будешь наблюдать квадратики. Именно для этого и нужен «TCP».
                                                                                          Ответить
                                                                                          • показать все, что скрытоvanished
                                                                                            Ответить
                                                                                            • > В течение какого времени?
                                                                                              Зависит от кодека, но никак не меньше нескольких (возможно, десятков) кадров. Повторюсь, не заметить такое сложно.

                                                                                              > Надо еще учитывать, что ya.ru это не видеохостинг, и отвечать мне на ping они вообще не обязаны.
                                                                                              Для любых других серверов картина ничуть не лучше. Постоянная небольшая потеря пакетов — это зло, от которого избавиться в принципе невозможно. Ну, разве что провести оптику от твоего компа к серверу «Твича».

                                                                                              Кстати, я совершенно забыл упомянуть, что порядок прихода пакетов в «UDP» не гарантирован. Поэтому для передачи видео по «UDP» тебе в любом случае придётся реализовывать подмножество «TCP» с сегментами и их буфером.
                                                                                              Ответить
                                                                                      • показать все, что скрытоvanished
                                                                                        Ответить
                                                                                        • Да.

                                                                                          > TCP более предпочтителен: он забуферизирует данные, сделав процесс smooth для пользователя: он будет перепосылать сегменты, пока пользователь смотрит видео.
                                                                                          На самом деле не совсем. Существует два буфера: системного уровня, который заполняется ядром (драйвером TCP/IP), и буфер браузера. В первом хранятся сегменты TCP, во второй браузер складывает кадры видео.
                                                                                          «TCP» гарантирует, что последовательность байт, отправленная с сервера, обязательно дойдёт до клиента без изменений и в правильном порядке (что тоже крайне важно, кстати). Буферизация видео браузером, в свою очередь, обеспечивает пользователю плавное воспроизведение даже тогда, когда приход очередной порции байт с сервера задерживается (драйвером TCP/IP) из-за потерь пакетов.

                                                                                          > Однако, TCP это бОльшая нагрузка на CPU.
                                                                                          По сравнению с декодированием [email protected] видео — это настолько мелкие копейки, что ими нужно пренебречь.

                                                                                          > Итого: если мы уверены в более-ли-менее качественном интернет-соединении, то имеет смысл использовать UDP.
                                                                                          Да, но такое будет только если сервер и клиент соединены напрямую одним кабелем. И даже в этом случае пользователь может поставить качаться торрент и получить багор.
                                                                                          Увы, Интернет — крайне непредсказуемое говно, поэтому получить по-настоящему надёжное соединение до удалённого сервера, к сожалению, невозможно. Возвращаясь к примеру выше, чтобы надёжно передавать видеопоток через «UDP» и получать квадраты хотя бы не чаще раза в минуту, нужно терять не больше одного пакета из 224640.
                                                                                          Ответить
                                                                                          • показать все, что скрытоvanished
                                                                                            Ответить
                                                                                            • > Я говорю с точки зрения провайдера: он может стримать UDP, и это позволит ему сэкономить ресурсы.
                                                                                              Настолько мизерные крохи ресурсов, что ими можно и нужно пренебречь. Там одно только TLS-шифрование потока сожрёт на два порядка больше ресурсов, чем обработка «TCP».

                                                                                              > Тогда почему у меня нормально работает IPTV по мультикасту от провайдера?
                                                                                              Нужно смотреть протокол и кодирование. Я же не говорю, что по «UDP» в принципе нельзя передать видео, я говорю о том, что это очень сложно и геморройно. Можно жать кадры по отдельности, тогда небольшая потеря пакетов действительно не будет заметна. Можно впендюрить десяток-другой процентов избыточности. Ещё как-нибудь извратиться.

                                                                                              Спокойной ночи.
                                                                                              Ответить
                                                          • Если «TCP» деградировал до такого уровня задержки — это значит, что потери пакетов в сети такие, что через «UDP» ты даже «Hello World» не передашь.
                                                            Ответить
                                                            • показать все, что скрытоvanished
                                                              Ответить
                                                              • > Не лучше ли проебать один кадр

                                                                Там такая дикая зависимость между кадрами, что всё на квадратики рассыпется до следующего ключевого. Не особо лучше чёрного экрана.
                                                                Ответить
                                                              • Если ты проебал один кадр (любой!) — все следующие за ним испаряются (до ключевого). В этом и проблема.

                                                                > ты проебал пакет, и получит передачу всего говна
                                                                Что? Какого говна?
                                                                Ответить
                                                                • >Если ты проебал один кадр (любой!) — все следующие за ним испаряются (до ключевого)

                                                                  Не совсем правда.

                                                                  Можно удачно проебать B-frame, на который никто не ссылается.

                                                                  Можно проебать P-frame, но на следующем обновить.

                                                                  Кодеки очень адаптивные и резистетные к ошибкам на самом деле.

                                                                  Очень сильно зависит от настроек адаптивности энтропии и кодека.
                                                                  Ответить
                                                                • показать все, что скрытоvanished
                                                                  Ответить
                                                                  • > с потерянным кадром

                                                                    Не, на него хуй забьют. buffering будет пока буфер не наполнится на безопасную для твоего канала глубину.
                                                                    Ответить
                                                                  • > TCP передаст тебе большой кусок, если ты потерял из него хоть один пакет.
                                                                    Нет. Потеряться может только IP-фрейм (1500 байт брутто). В таком случае «TCP» просто передаст этот фрейм ещё раз.

                                                                    > Рассмотрим ситуацю, когда ты потерял НЕ ключевой кадр.
                                                                    > В UDP ты этого не заметишь
                                                                    Нет, не так. Если я потерял НЕ ключевой кадр, то у меня ВСЕ последующие НЕ-ключевые кадры превратятся в квадратики. То есть, в зависимости от кодека, я буду эдак секунду-другую (точное время надо у кодировочных петухов спрашивать) смотреть на квадраты.

                                                                    > в TCP ты будешь вынужден смотреть на "buffering", пока ты не переполучишь кусок с потерянным кадром, нет?
                                                                    Нет, см. первый абзац.
                                                                    Ответить
                                                                    • показать все, что скрытоvanished
                                                                      Ответить
                                                                      • > Стоп. Давай определимся с терминологией: IP пакет размером 1500 байт, что такое фрейм?
                                                                        Перепутал с «Ethernet».

                                                                        > TCP передаст сегмент целиком, не?
                                                                        Да. При этом сегменты запихиваются в IP-пакеты, поэтому один сегмент — это не больше 1500 байт. См. «MSS».

                                                                        > Разве не ключевой кадр это не diff к предыдущему ключевому?
                                                                        Ключевой кадр — это, грубо говоря, просто пожатая стандартными алгоритмами картинка, JPEG. Диффы последующих не-ключевых кадров считаются от него. То есть (опять же, очень грубо говоря, видеопетухи поправят) тебе передаётся (key_frame, data_1, data_2, ...); frame_1 = diff(key_frame, data_1), frame_2 = diff(frame_1, data_2), frame_3 = diff(frame_2, data_3), etc. Каждый последующий не-ключевой кадр зависит от предыдущего, как в «AES CBC».
                                                                        Ответить
                                                                        • показать все, что скрытоvanished
                                                                          Ответить
                                                                          • > Таким образом, я сосу болта до следующего ключевого кадра, верно?
                                                                            Да.

                                                                            > я или смотрю на квадратики до следующего ключ кадра, или смотрю на "buffering"
                                                                            Нет. Ключевая разница в том, что в «TCP» ты смотришь на «buffering» один раз, после чего буфер у тебя разрабатывается, и дальше ты видишь только плавную картинку без единого разрыва.

                                                                            > то ключевой кадр может быть размазан на несколько пакетов
                                                                            Не знаю, не видел этой технологии.
                                                                            Ответить
                                                                            • показать все, что скрытоvanished
                                                                              Ответить
                                                                              • Буферинг ты видишь не после каждой потери пакета, а только после тех потерь, которые не удалось устранить за длину буфера.

                                                                                Т.е. если у тебя буфер 10 секунд, то у тебя есть почти 10 секунд на загрузку каждого чанка. Ну и собственно отстаёшь от реалтайма ты на эти самые 10 секунд. TCP за это время без проблем успевает всё перепослать и переполучить.

                                                                                Ну а если канал пиздец хуёвый и не успевает - значит будешь жить с буфером в 20 секунд. Хотя обычно после такого просто качество скидывают.
                                                                                Ответить
                                                      • Почитай как работает хлс/даш. Ты клиент хттп, ты сам по хттп забираешь все чанки. Сервер же готовит на сервере к готовности плейлисты (перечень чанков) и сами чанки в нескольких разрешениях сразу (качестве).

                                                        Ты качаешь по хттп плейлист и по хттп начинаешь качать чанки. Понимая, что плейлист - активный стрим, ты перезапрашиваешь плейлист раз в эн секунд, чтобы узнать о новых свежих чанках, которые тоже будешь сливать с сервера по хттп.

                                                        Плеер твой может догадаться, или ты сам, о том, что твой канал говно, он не успевает вовремя качать, все тормозит и дёргается - есть возможность переключиться на качество похуже (чанки будут за те же промежутки времени, но по размеру меньше заметно).

                                                        Вот в этой схеме задержку менее 15 секунд практически нереально получить (потому что чанк должен быть не на 1 секунду), а оптимально - 60 секунд.

                                                        Когда ты смотришь футбол онлайн, это норм, когда смотришь куранты с путиным на новый год - это тоже приемлемо.

                                                        А вот для диалога - нет.
                                                        Ответить
                                                        • Да ну не 15, меньше обычно, что-то в пределах 10 с чанками в пару секунд. Но для диалога это не особо пригодно, да. Как с луной разговариваешь, даже если обратный канал через текстовый чатик.
                                                          Ответить
                                                        • Щас много ебанутых, которые играют на ставках, для них минута задержки это может быть критично: в популярном матче за это время котировки могут прыгнуть несколько раз.

                                                          Впрочем, для этих целей наверняка лучше использовать вменяемые текстовые трансляции.

                                                          Интересно, какая задержка при ТВ-трансляции
                                                          Ответить
                                                    • Была программа «rtmpdump», чтобы тырить данные с видеосервисов, которые отображают кинцо через «Плоть». Например, с «Rutube» только так можно было снять поток.
                                                      Ответить
                                                  • Ну, например, чтобы не ебаться с потерей пакетов, попутно изобретая свой собственный «TCP» поверх «UDP». Видеопоток — это же не просто кучка отдельных кадров, это закодированная кучка кадров. После потери полутора килобайт данных их придётся либо пересылать (изобретаем «TCP»), либо показывать пользователю секунду-другую пустоты, до следующего ключевого кадра (любой пользователь с дропрейтом > 0.00..01% будет смотреть на чёрный экран).
                                                    Ответить
                                                • Тут бы p2p
                                                  Ответить
                                        • Ну я ща на твиче проверял - просто чанки по HLS, если верить консоли браузера.
                                          Ответить
                                          • Ну как я и сказал
                                            Ответить
                                          • >просто чанки по HLS, если верить консоли браузера

                                            Да. И это гнусно что HLS кругом.

                                            Впрочем на твиче лайф-стримы. Для них это как раз вполне нормально.
                                            Ответить
                                        • ЕМНИП конкретно твич энкодит очень маленькие кусочки по 50 кадров. Около 2х секунд.

                                          И они их могут ворецировать как пожелают, адаптивно меняя качество под скорость канала пользователя.
                                          Ответить
                                          • О, может ты знаешь, там же high-res поток как дельта от low-res потока кодируется? Чтобы можно было быстро переключаться на хуёвое качество и обратно.
                                            Ответить
                                            • >О, может ты знаешь, там же high-res поток как дельта от low-res потока кодируется?
                                              > Чтобы можно было быстро переключаться на хуёвое качество и обратно.

                                              Это называется SVC.

                                              Хз как на твитче. Но вряд ли. Т.к. в я не видел толковых реализаций в промышленных энкодерах.

                                              >Чтобы можно было быстро переключаться на хуёвое качество и обратно.
                                              Одно я знаю наверняка. Твитчовцы (и это их заслуга) для этих целей пролоббировали в AV1 совершенно потрясную штуку.

                                              Называется S-frames.

                                              https://www.youtube.com/watch?v=o5sJX6VA34o
                                              https://thebroadcastknowledge.com/2020/04/15/video-s-frame-in-av1-enabling-better-compression-for-low-latency-live-streaming/
                                              Ответить
                                          • Если стример стримит через OBS, который сам сжимает как ему надо, то в случае, который ты описал, Твитч сначала декодирует, потом кодирует заново что ли? Или как это происходит?
                                            Ответить
                            • > А на задержку там всем похуй на самом деле, ну ответит тебе стример на 5 секунд позже, не помрёшь.
                              Да нет, они в последнее время серьёзно за её уменьшением гонятся (как и «Ютуб», кстати). Две секунды задержки от компьютера стримера — это реальный пример.
                              Ответить
                              • показать все, что скрытоvanished
                                Ответить
                              • Как на Ютюбе 2 секунды получить?
                                Ффмпег ебаный это уже секунда, даже если ты такой охуевший и в полуреальном времени срешь на клиенты по вебсокету (а не мпег-даш/хлс), 2 секунды и массовость звучат фантастично

                                (И главное, зачем? Что плохого в задержке, например, 30с?)

                                Я прост далёк от блогиров, но тема интернет вещания регулярно возвращается в контекст
                                Ответить
                                • > Как на Ютюбе 2 секунды получить?
                                  Не знаю, я на «Твиче» специализируюсь. Реальный пример: https://i.imgur.com/DGN5EK0.png.
                                  Правда, меня смущает размер буфера: если буфер 2.06 секунд, а задержка — 2.09, получается, мне от стримера кадры приходят за 30 миллисекунд?..
                                  Наверное, «Твич» всё таки запутался в терминах, и реальная задержка (отставание часов на экране стрима от моих локальных) там 4.15 секунды.

                                  > И главное, зачем? Что плохого в задержке, например, 30с?
                                  Ну типа мгновенная реакция на чат, все дела.
                                  Ответить
                                  • Такие задержки логичны в конференцсвязи. Когда ты ведёшь диалог с собеседниками.
                                    Диалог в конфе овер, скажем, 50, вести сложновато.

                                    Ну разве что в твиче модный блогир типа тоже диалог ведёт, с текстовым чатом. Ясно
                                    Ответить
                                    • > Ну разве что в твиче модный блогир типа тоже диалог ведёт, с текстовым чатом
                                      Подтверждаю. Интерактивность.
                                      Ответить
                            • > Я могу ошибаться, но по-моему low-res потоки тоже на компе стримера создаются.

                              Сорянчик, что вмешиваюсь в экспертную беседу со своим профанизмом.

                              https://youtu.be/LsF5bHRxC_M?t=234

                              В принципе там довольно подробное описание работы твитча.
                              Ответить
                          • Походу таки сам ужимает, по крайней мере я в настройках не вижу ничего про low-res потоки.
                            Ответить
                      • показать все, что скрытоvanished
                        Ответить
    • Я просто оставлю это здесь:

      https://govnokod.ru/25131
      Ответить
    • Ну я ради интереса запустил aomenc
      А там такое:
      $ aomenc --help
      --global-error-resilient=<  Enable global error resiliency features
      
      --error-resilient=<arg>     Enable error resilient features (0: false (default), 1: true)
      
      --cdf-update-mode=<arg>     CDF update mode for entropy coding (0: no CDF update; 1: update CDF on all frames(default); 2: selectively update CDF on some frames

      CDF ­— энтропийное кодирование.

      За сим иду спать. Доброй ночи.
      Ответить
    • О чём вообще спорить?
      1. Взять ffmpeg+x264 зожать.
      2. Пропустить через какой-нибудь tc с заданным дропом.
      man netem
      3. Воспроизвести полученный файл ffplay.
      Ответить
      • да, так лучше всего)

        только man tc-netem вроде)
        Ответить
    • Я кстати из тредика не понял одной вещи:

      Если видео записано заранее, то лучше всего взять Adaptive bit rate, когда сервер разбивает всё на кусочки, а клиент выбирает следующий чанк нужного размера.

      Если клиент сидит на iPhone через сотовую сеть, то он выберет кусочек с худшим качеством (и худшего размера)
      А если у него телек на пол стены по гигабиту, то может позволить себе чанк по лучше

      Все эти проты работают по TCP, и это понятно: клиент может накачать себе чанков за щеку, как хомяк, и их показывать.

      А если видео стримается в реальном времени? Если это видеокамера с улицы?

      Я не смогу наполнять буфер быстрее, чем я его опустошаю, какой же тут толк от TCP по сравнению с UDP?

      Получится, что потерянные пакеты приведут или к замиранию картинки, или к buffering.

      Можно конечно забуферизировать данные, и показывать камеру с отставанием, но если это видеозвонок или прямой эфир, и туда можно звонить? Тогда отставать мне нельзя.
      Ответить
      • > Я не смогу наполнять буфер быстрее, чем я его опустошаю
        А зачем? Ты открываешь стрим, браузер закачивает две секунды стрима и начинает тебе его показывать, параллельно закачивая следующие две секунды потока. В «UDP» будет то же самое: тебе так же надо организовать буфер в несколько секунд видеопотока, чтобы, во-первых, восстановить порядок UDP-пакетов (они к тебе придут перемешанные), а во-вторых — не раздражать пользователя из-за флуктуаций пинга (видео, в котором каждый кадр показывается с задержкой +- пару миллисекунд от номинальной будет выглядеть очень… своеобразно).

        > Получится, что потерянные пакеты приведут или к замиранию картинки, или к buffering.
        Только в том случае, если у тебя теряется порядка процента и больше пакетов, и то только ОДИН РАЗ. После этого одного раза буфер разработается и buffering не будет, за счёт увеличения задержки.
        Ответить
        • А где вообще сегодня используют UDP?
          Ответить
          • Там, где небольшие (сотые/тысячные доли процента) потери данных не важны, либо из-за избыточности, либо из-за переизобретённого «TCP», при этом «TCP» в чистом виде не подходит (увеличение задержки, оверхед на установку соединения, принципиальная невозможность установки соединения как в мультикастовом «IPTV»). То же видео может передаваться по «UDP», когда задержки в единицы секунд крайне критичны (видеозвонки, конференции: см. «RTMFP», кажется, «Скайп» работал по «UDP»). Многие мультиплеерные игры, требовательные к задержке (шутеры там всякие), тоже ходят по «UDP».
            Ответить
            • Ну вот про звонки я догадывался. Не только видео, но и VoIP в принципе.

              Помню, как на стороне заказчика юные телекомщики с восторгом рассказывали, как они поменяли с TCP на UDP и всё полетело.

              Думал, что в видеостриминге в принципе это норма, но вы меня переубедили.
              Ответить
          • В мультикасте, например.

            OpenVPN может по udp, чтобы не делать накладных расходов
            Ответить
            • > OpenVPN может по udp, чтобы не делать накладных расходов
              Точно, про него забыл. В «OpenVPN» запилен свой протокол, обеспечивающий надёжность передачи данных, поэтому гонять его по «TCP» — практически бессмысленное занятие.
              Ответить
              • По TCP можно косплеить https, чтобы обманывать админа, например.

                А зачем VPN надежность? Интернет же ненадежен, и поверх него работают другие проты. VPN вполне себе может эмулировать такой вот ненадежный Интернет
                Ответить
                • У VPN обычно вшита защита от повторов и модификации пакетов. Не потому что инет хуёвый, а потому что люди злые.
                  Ответить
                • > По TCP можно косплеить https, чтобы обманывать админа, например.
                  Да, и про это забыл. Пускаем «VPN» на 443-й порт и течём.

                  > А зачем VPN надежность?
                  Надо читать протокол. Могу предположить, что он у них завязан на последовательное получение сегментов (типа «AES CBC»), тогда любая потеря пакета приведёт к разрыву соединения.
                  Ответить
        • То-есть я всегда буду отставать на 2 секунды?

          >восстановить порядок UDP-пакетов
          Пришедший в неверном порядке пакет можно же просто отбросить?

          Если браузер всё равно имеет свой буфер, то зачем мне еще и буфер tcp?

          >После этого одного раза буфер разработается и buffering не будет, за счёт увеличения задержки.

          А как это всё будет работать с прямым эфиром или видеозвонком?
          Ответить
          • > То-есть я всегда буду отставать на 2 секунды?
            Да.

            > Пришедший в неверном порядке пакет можно же просто отбросить?
            Можно. Тогда у тебя останется примерно половина пакетов, может даже меньше.

            > Если браузер всё равно имеет свой буфер, то зачем мне еще и буфер tcp?
            Потому что это два разных буфера с разными функциями. Буфер «TCP» нужен для восстановления исходного потока байт с сервера, буфер браузера — для обеспечения плавного воспроизведения видео без прерываний.

            > А как это всё будет работать с прямым эфиром или видеозвонком?
            Для прямого эфира это совершенно непринципиально (так, например, многие играющие в онлайн-игры стримеры специально выставляют задержку в одну-две минуты, чтобы противники не могли подсмотреть стрим и получить преимущество). Для видеозвонков используются либо более мелкие буфера, либо какие-то формы избыточности (возможно, в связке с «UDP», надо смотреть протоколы).
            Ответить
            • >Можно. Тогда у тебя останется примерно половина пакетов, может даже меньше.

              А есть какая-то статистика на этот счет?

              >Потому что это два разных буфера с разными функциями.
              То-есть TCP нам нужен исключительно для восстановления порядка?

              >для видеозвонков
              Ну вот skype используе UDP
              https://support.skype.com/en/faq/FA148/which-ports-need-to-be-open-to-use-skype-on-desktop

              Если ты утверждаешь, что половина пакетов у меня потеряется или придет в неверном порядке, то как же эту проблему решает скайп?
              Сам восстнавливает порядок пакетов?
              Ответить
              • Да, у звонилок тоже есть буфер, просто он там десятки-сотни миллисекунд а не десятки секунд как у лайв стримов.

                Проблема не столько в порядке, сколько в джиттере - задержку постоянно "трясёт". Поэтому точно так же поток приходит кусками и какое-то время отстаивается в буфере.
                Ответить
                • джиттер это когда у тебя пинг 12 потом 56 и снова 12?

                  Так буфер у них свой, выполнящий и буферизацию, и восстановление порядка, итд, а сами они по udp?
                  Ответить
                  • Судя по тому, как у меня при разговоре по Скайпу шумят вентиляторы, то он там ещё заодно и нейронку подключает для генерации недостающих фрагментов
                    Ответить
                  • Ну да, кусочки вставляются в буфер по мере их получения. И равномерно выгребаются на воспроизведение. Если пришёл слишком старый кусок - выбрасывется нахуй. Если пришло время воспроизводить, а нужного куска так и нет - ну не судьба, посмотрим на квадратики или послушаем тишину.
                    Ответить
                    • Ну вот если я верно понял госта, то TCP все это прекрасно делает (кроме выбрасывания), зачем же тогда оин не tcp?

                      Большой оверхед для такого мелкого буфера?
                      Ответить
              • > А есть какая-то статистика на этот счет?
                Нет, только эмпирические наблюдения за «tcpdump».

                > То-есть TCP нам нужен исключительно для восстановления порядка?
                Для восстановления порядка и восстановления потерянных пакетов.

                > то как же эту проблему решает скайп?
                Изобретением своего велосипеда. Поверх «UDP» написан охулиард протоколов разной степени надёжности, в той или иной мере копирующих «TCP». См. «RDP», «RUDP», «ENet», «GameNetworkingSockets», тысячи их.
                Ответить
                • >эмпирические
                  Надо бы проверить. Почему половина пакетов идет в другм порядке? Потому что разными путями идут?

                  RDP работает и поверх UDP и поверх TCP, кстати
                  Когда хорошее подключение, он мигрирует на UDP))

                  Вопрос: почему же WebRTC, Skype, RTP и пр не использовали tcp?
                  Ответить
                  • > Вопрос: почему же WebRTC, Skype, RTP и пр не использовали tcp?

                    > RTP
                    >>> В заголовке данного протокола, в частности, передаются временная метка и номер пакета. Эти параметры позволяют при минимальных задержках определить порядок и момент декодирования каждого пакета, а также интерполировать потерянные пакеты.
                    Здравствуйте, мы изобрели «TCP».

                    > WebRTC
                    >>> Finally, a special error-concealment algorithm is used to hide the negative effects of network jitter and packet loss
                    Здравствуйте, мы изобрели «TCP».

                    > Skype
                    >>> The Skype team anticipated some jitter and packet loss, and therefore have algorithms that can deal with these problems.
                    Здравствуйте, мы изобрели «TCP».
                    https://www.gsx.com/resources/blog/udp-vs-tcp-what-is-really-best-for-skype-for-business-voice/
                    Ответить
                    • показать все, что скрытоvanished
                      Ответить
                      • Основной недостаток «TCP» — это оверхед на соединение (SYN, ACK, SYN-ACK), так что, скорее всего, в нём. От стейтфул соединений нагрузка слишком низка, чтобы её можно было заметить.

                        Ну и ещё есть «NIH».
                        Ответить
                      • В другом месте немного иначе написано:

                        A dynamic jitter buffer and error concealment algorithm used for concealing the negative effects of network jitter and packet loss. Keeps latency as low as possible while maintaining the highest voice quality.

                        Но у меня нет соблазна сравнивать это с TCP
                        Ответить
                        • > Keeps latency as low as possible while maintaining the highest voice quality.
                          Ну, то есть они изобрели «TCP», оптимизированный для их протокола и профиля использования. Тоже валидный кейс.
                          Ответить
                          • Мне не нравится формулировка «они изобрели TCP». Они (вероятно) реализовали часть его фишек вообще на другом уровне абстракции.

                            Зачем им изобретать TCP, пусть даже оптимизированный, как ты говоришь, если TCP уже есть? Это оверинжениринг
                            Ответить
                            • > реализовали часть его фишек вообще на другом уровне абстракции
                              Ну так это и есть изобретение велосипеда. В данном случае, конечно, оправданное: велосипед у них получился специализированный и более подходящий для решения их задачи, вот такой: https://www.youtube.com/watch?v=PIoUKPeWVjQ.
                              Ответить
                              • Хе-хе, я думал, там скринкаст какой.

                                Интересно, Борманд так и не заинтересовался Твитчем и видеостримингом после этих всех бесед? По-моему, такое широкое минное поле для байтоёба!)
                                Ответить
                                • Мне аудиозвонков хватило. Одно дело просто попиздеть про всё это, и совсем другое - поддерживать совместимость со всяким кривым говном, с которым это всё должно будет работать.
                                  Ответить
                                  • А ты занимался аудиозвонками? А что там был за стек, если не секрет?
                                    Ответить
            • Кстати, WebRTC тоже udp, но как именно -- надо почитать
              Ответить
    • https://www.youtube.com/watch?v=O9JmP0Zwz1s

      Стрим с камеры, задержка ~30 секунд
      Ответить

    Добавить комментарий