LINUX.ORG.RU

Сообщения gobot

 

Как перехватывать все сообщения

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

Может ли RabbitMQ такое сделать: приходит сообщение в очередь, он берет его и отправляет целевому потребителю и ещё моему потребителю. Вот как его заставить это сделать?

Использую nodejs c либой amqplib, сервер RabbitMQ на Ubuntu...

 ,

gobot
()

Не импортируется класс

Хочу сделать авторизацию через Facebook в своем приложении (java).

Делаю все по инструкции https://github.com/facebook/facebook-android-sdk


import com.facebook.login.LoginManager;
...

LoginManager.getInstance().registerCallback(CallbackManager.Factory.create())

LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("public_profile", "user_friends"));


проблема в том, что Android Studio не видит com.facebook.CallbackManager, и вообще все что находится тут https://github.com/facebook/facebook-android-sdk/tree/main/facebook-core/src/...

В зависимости gradle добавил целиком весь SDK
implementation 'com.facebook.android:facebook-android-sdk:12.2.0'

Во всех их примерах используется CallbackManager, например тут

Возможно потому что там kotlin? Хотя в их примере тоже используется java...

В чем может быть причина?

 , , , ,

gobot
()

Разделитель x0 x0 x0 x1 NAL units

Ковыряю h264 bitstream, в частности разделитель (start code) границы NAL unit. Никогда не копался в этих битах и байтах, но нужно доковырять кодировщик
Везде пишут (например ), что разделитель, стартовый код (start code), от которого начинается последовательность NAL блоков(units?) это

1 байт - 00000000
2 байт - 00000000
3 байт - 00000000
4 байт - 00000001

Ну или 3 байта бывает, но последний 00000001 должен.
Смотрю потом hex редактором сохраненный поток h264 (в FLV формате)

0000 00 00 00 0E 67 42 C0 29 8C 8D 40 5E 1A 90 0F 08
0010 84 6A 00 00 00 04 68 CE 3C 80 00 00 36 E1 65 B8
0020 00 03 00 00 03 01 0F FF F8 70 B4 50 00 21 7E F8
0030 E0 0C 73 08 7A FF FE 4E 10 CE BF FF F7 08 65 51


и вижу что верно, первые 3 байта - нулевые, а четвертый вовсе не 1 (как предпологалось), а некое другое число (x0E), который указывает длинну NAL unit"a (это я понял эксперементально и вроде это так, если отсчитать от него 14 байтов, то мы перейдем к следующему NAL - PPS), дальше, после x0E уже идет заголовок NAL (x67 - 01100111 - его заголовок, который указывает что NAL ref -3 (биты 11) и NAL type - 7 (SPS) (биты 00111)), дальше идет другой NAL блок - PPS (начитается от x68, 01101000 - тут 11 - 3 (NAL ref) и 01000 - 8 (код PPS)). Три байта нули...

Дальше идет сам IDR (x65 - 01100101 - 00101 - 5 (IDR nal)), тут уже разделитель 2 нулевых байта...

Не понятно с разделителями и не понятно где укзано про длинну.

Также заметил, что мой кодировщик(MediaCodec android) правильно ставит стартовые коды, а именно
00000000
00000000
00000000
00000001

но потом в коде эти коды вырезаются и вместо них устанавливаюся новые, тоже 4 байта
0
0
0
последний байт это длинна NAL блока

Тут тогда понятно, откуда берутся такие разделители. Но не понятно почему ставят длинну, а не просто 00000001 в конце

Может кто знает про разделители?

 , , ,

gobot
()

Изменение параметров кодирования(разрешения) на лету

Я делаю приложение для Android, которое передает в реальном времени видео и звук по протоколу RTMP. Для этого я захватываю звук и камеру и отправляю их буферы по кусочкам в MediaCodec для кодирования, далее оформляю все это в FLV пакеты и отправляю в созданный RTMP-поток.

Все хорошо работает, за исключением следующего: если на «лету» изменять параметры кодирования, в моем случае это разрешение, то мне приходится переконфигурировать этот самый MediaCodec

public void reconfigure(){

    //сначала останавливаю кодировщик
    vencoder.stop();
    vencoder.release();
    vencoder = null;

    //затем создаю новый, в настройках меняю только разрешение
    vencoder = MediaCodec.createByCodecName("OMX.MTK.VIDEO.ENCODER.AVC"); //MediaCodec
    MediaFormat videoFormat = MediaFormat.createVideoFormat("video/avc", 640, 480);
    videoFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, 21);
    videoFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 0);
    videoFormat.setInteger(MediaFormat.KEY_BIT_RATE, 1200 * 1024);
    videoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 24);
    videoFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 2);
    vencoder.configure(videoFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    vencoder.start()
}


и продолжаю в этом же Thread, кодирование. Далее кодировщик отправляет новый SPS (nal_unit_type = 7) в поток и ключевой кадр(nal_unit_type = 5, IDR). Кодирование продолжается, но плееры «падают» в этот момент, либо идет только звук, а видео нет. С временными метками(DTS, PTS) все нормально, они продолжают увеличиваться. Единственный плеер который корректно производит поток это ffplay, этот мамонт все сжирает.

Ссылка на исходник, где идет кодирование видео https://github.com/begeekmyfriend/yasea/blob/f118e6e1c30460215dde6de37a899c29...

В чем может быть дело?


UDP: если передавать только видео, то проблемы со сменой разрешения нет

UDP2:
FFMPEG выдает ошибку на переходном AAC фрейме (с которого все начинает глючить)
Input buffer exhausted before END element found

В исходниках это
https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/aacdec_template.c#L3382

и ещё в логах появляется
stereo with SCE

Похоже не нравится малый размер AAC пакета, что-ли

≈=======
Решил проблему так:

Останавливаю видео-кодировщик не сразу, а после того, когода он отправит все predicted (P) фреймы, которые начинаются от Intra. Теперь Хром и ФФ проглатывают это и видео, меняют разрешение и не останавливаются.
Аудио-кодировщик не перезапускаю

Не понимаю до сих пор почему это помогло. После перезапуска ведь отправляется sps, pps и idr пакет. Там вся инфа содержится. Кодеку нужно лишь переконфигурироваться. Как влияют P фоеймы?

И еще, если декодировать в ффмпег h264_qsv, то видео все равно зависает. С чем связано пока не понял.


UDP. Нашел проблему. В начале потока отсылался только AVC SequenceHeader(в FLV type=0), в последущем отсылался также он, что не правильно: игнорировался FLV-демультиплексором и не обрабатывался h264 декодером. Нужно в середине потока посылать NAL unit(в FLV type=1)

 , , , ,

gobot
()

Миллионы смартфонов и компьютеров лишат доступа к интернету

https://lenta.ru/news/2021/09/29/connection/

Что делать?
Проблема сейчас есть. Сервер - linux debian

ERROR: The certificate of ‘xxx.com’ is not trusted.
ERROR: The certificate of ‘xxx.com’ has expired.

 ,

gobot
()

jcenter накрылся

Сидел тут, потихоньку кодил в Android Studio, потом заметил что при сборке gradle долго какой-то maven-metadata.xml скачивает и завершается с ошибкой read timeot. Погуглил, узнал, про репозитории, где хранятся java проекты.

Вообщем оказывается что jcenter признали устаревшим и рекомендуют переходить на Maven Central.

Ну, хорошо, подумал я, делов то, нужно ведь просто добавить mavenCentral в gradle конфиг и убрать jcenter

allprojects {
    repositories {

        //jcenter()
        google()
        mavenCentral()



    }
}


Добавил, все хорошо, в целом, но у меня есть некоторые пакеты, которые находятся только в jcenter и нигде больше их нет. Это, например, exoplayer, который имеет зависимость rtmp-client, которая есть только в jcenter. Иду в github в Issues, нахожу там где пишут что сие нужно переносить из jcenter, на что был ответ

I see. Thank you.
I think we definitely add the lib to the maven repo or somewhere.

Типа да это круто, мы когда-нибудь добавим нашу библиотеку в репозиторий maven или еще куда-нибудь, но пока ее нигде нет кроме как в jcenter. Как выяснилось, не добавили.

Потом искал эти пакеты на https://mvnrepository.com/ это вроде как агрегатор репозиториев. Добавлял репы, но ни к чему это не приводило, либо репа выдавала 404, либо 500, либо 403 ошибку.

В общем, у меня есть проект в Android Studio, жил он с этими зависимостями около 3 лет

android {
  dependencies {
    implementation 'com.google.mlkit:barcode-scanning:17.0.0'
    implementation "androidx.camera:camera-camera2:1.0.1"    
    implementation 'com.squareup.okhttp3:okhttp:4.9.0'

    implementation 'com.google.android.exoplayer:exoplayer:2.15.0'
    ...
  }
}


который собирался, запускался и работал. Сейчас я его не могу запустить, потому что не работает какой то там jcenter. Получается никто за это не отвечает, я пользовался этим на свой страх и риск? Я ничего не понимаю

 , , , ,

gobot
()

как ffmpeg отрубаться когда нет данных на входе

Здравствуйте!
Никак не могу подобрать волшебный ключик к этой программе.
Есть сразу два вопроса из одной оперы.

1. Проблема вот в чем: записываю видео по протоколу rtmp в контейнер mp4 (но не суть). Все отлично, если бы ffmpeg после завершения стрима отрубался и завершал муксирование контейнера. Но он ждет чего то. Ключиком к отрубанию должна быть команда rtmp протокола NetStream.Unpublish. Он ее либо не видит, либо не знает про нее, либо знает но молчит. Т.е. ffmpeg переходит в вечную паузу, надеясь что поток продолжится когда либо. Также происходит со стартом, если стрим ещё не запущен, ffmpeg будет ждать его начала, тоже бесконечно.

Пробовал

-abort_on empty_output empty_output_stream
-muxdelay 1
-muxpreload 1

не подошло

Да, начал конечно программно шаманить, запускал ffmpeg через php скрипт и там уже мониторил. Проперял изменение в размере записанного файла, если размер 5 раз не меняется, то я считаю что запись завершена

2. Как корректно убивать ffmpeg? Ок, когда он в так сказать активной работе то убивается хорошо и INT и TERM сигналами с первого раза (Exiting normally, received signal 2.). Когда он в «вечной паузе», то первое послание сигнала INT (или TERM не важно) - никакой реакции, второй посыл такого же сигнала - убивается как Terminated, то есть не корректно. Поэтому не записывает атом в конец mp4 контейнера и файл не читабется. Почему со второго раза убивается и почему аварийно terminated?

 

gobot
()

Парсер смайликов

Есть html

Hello :smile: <strong>world</strong>


Нужно заменить в нем :smile: на <img src=«/i/smile.gif»/>, но также убрать все пользовательские теги
В итоге должен получиться следующий html
Hello <img src="/i/smile.gif"/> &lt;strong&gt;world&lt;/strong&gt;


Пробовал через дерективу
Vue.directive('parse-smiles', {

    bind: function (el, binding, vnode) {

    },
    inserted: function(el, binding, vnode){
        el.innerHTML = replaceCodes(el.innerHTML); //тут по регулярке заменяет коды на картинки
    }

});


Шаблон
<div v-parse-smiles="{}">{{text}}</div>


Работает, но теряется реактивность. Если к div добавить, например, v-if

 

gobot
()

Скорость сети на сервере

На сервере анлим 500mbps, по графикам zabbix видно что действительно скорость отдачи\загрузки бывает и 100 и 200 mbps и выше. Но стоит мне со своего компа начать загруку какого нибудь файла по http или FTP так скорость не превышает 1-2mbps (интернет
дом.ру 100mbps).

speedtest.net показывает ping 1ms, dowload 84mbps uplaod 74mbps.

На самом сервере тестил через speedtest-cli, все четко 438\417mbps

В чем затык, где узкое место?

UPD. И да, это не зависит от географической локации загрузки, жалуются на скорость все пользователи сервера

UPD2. Проверял также скачку с другого сервера по wget, скорость не прквышает 1mbps

UPD3. Когда с сервера загружаю http://ipv4.download.thinkbroadband.com/512MB.zip то скорость загрузки отличная, поднималась до 30mbps

UPD4. Проверял по FTP - скорость также маленькая, не превышает 1mbps

 , , ,

gobot
()

Клава для властелина

Ищу клавиатуру. Чтобы кнопки трескали как в 90х. Были выпуклые. Чоткие, короче. К последим клавам не могу привыкнуть, они плоские. Какие модели посоветуете?

 ,

gobot
()

node 8 vs node 15

Здравствуйте!
Приходится (в связи с переходом на webpack 5) обновить nodejs с 8 до ... более новой, но думаю до последней уж тогда 15 версии.
Пока боюсь обновлять. Подскажите, что может потенциально сломаться в моих скриптах, если до этого они 3 года работали на ноде 8? Специфицеского ничего не использовал, код довольно простой

И собственно как обновлять правильно?

# Using Debian, as root
curl -fsSL https://deb.nodesource.com/setup_15.x | bash -
apt-get install -y nodejs


так?

 

gobot
()

Часть строки как html

Здрасти
Есть vue...есть я... На этом можно было бы закончить ))

Есть шаблон, есть строка с текстом в которой есть подстрока с кодом смайлика, ну папримен :ugly:
В шаблон я разумеется хочу вставить эту строку {{mess}}. Хочу я также взять и заменить в этой строке код смайла на картинку. Вроде все тривиально, 6аписал регекс и хлоп - все. Так и есть, но вуй при вставке переменной экранизирует <img/>

Понятно, что я знаю про v-html и про вставку <component is>, но вот в чем затык, в строке могут быть другие теги(собственно это пользовательские данные) и их нужно экранировать. Но не можно экранировать мои <img>

На ум приходит только предварительно экранизировать всю строку самому (может в вуе есть функция?), потом парсить смайлы и прочее и уже готовую строку впендюривать в v-html

Может есть более лаконичный способ. Задача вроде типичная. Ну не разбивать же строку на компоненты.

Пример строки

Пнивет всем :ugly: я вася пупкин <script>alert("xss")</script>


Что хочу
Пнивет всем <img src="/ugly.gif"/> я вася пупкин &lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;


Шаблон
<strong>{{nickname}}</strong>
<div>{{mess}}</div>

 

gobot
()

Зачем гугл рекомендует делать сайты под текстовые браузеры?

https://developers.google.com/search/docs/advanced/guidelines/ajax?hl=ru

В частности, подумайте о тех, чьи браузеры не поддерживают JavaScript (например, людях, использующих программы чтения с экрана или старые телефоны)

Что за дичь в 21 веке? Для кого? Для чего? Кто реально поддерживает браузеры, где нет js?

 , , ,

gobot
()

Как найти админа

Хочу нанять админа сервера. Как ограничить доступ к БД и вообще к другим разделам, фоткам, например, пользователей? Как такое разруливают?


Перемещено leave из admin

 

gobot
()

Использование памяти

Что-то не могу понять. Смотрю в ТОП, у процесса колонка VIRT=6GB (RES=500MB), но в тоже время свопа в системе всего 512MB, причем весь он занят (как обычно, я уже забил на это и походу не лечится). В чем дело? Куда VIRT пишется? Процес какой-то мусор накапливает, можно ли его очистить и вообще нужно ли? Направьте на путь истинный..)

 ,

gobot
()

ffmpeg дропает кадры с камеры, если битрейд увеличивается (too full or near too full)

Вкратце: стримминг камеры(+звука) на rtmp сервисы через ffmpeg

Проблема в следующем: Кадры со входа дропаются, если битрейд передачи потока превышает ~400kbps.

По умолчанию, если ffmpeg получает видеокадр «слишком рано» (в то время как предыдущий кадр еще не закончен), он отбрасывает этот кадр, чтобы он мог поддерживать ввод в реальном времени

Вот что в доках:
https://trac.ffmpeg.org/wiki/DirectShow

By default FFmpeg captures frames from the input, and then does whatever you told it to do, for instance, re-encoding them and saving them to an output file. By default if it receives a video frame «too early» (while the previous frame isn't finished yet), it will discard that frame, so that it can keep up the the real time input.

Ну ок, тут вроде понятно, если кадры с камеры идут очень быстро, а я их не успеваю обрабатывать, то их нужно отбрасывать, для достижения реалтайма. Но я не вижу узких мест. Кодировщик настроен на минималку, FPS на входе и на выходе одинаков. Процессор нагружен на 2-3%. Сеть ДОМРУ ну где то 50Mbps. Сервер тоже тянет.

В целом все хорошо работает. Но сбился с толку уже с этим rtbufsize, который постоянно «too full or near too full», если битрейд превышает 400kbps

rtbufsize - буфер памяти для входа для realtime устройств. Я его установил в 10M(мегабайт). Играть с ним нет вообще никакого смысла, если установишь хоть в гигабайт, то все равно он со временем переполнится, а latency будет огромный

Камеру установил на минималку (640x480@20), выходной поток такой же (640x480@20), битрейд максимальный - 800k.

ffmpeg -f dshow -video_size 640x480 -framerate 20 -rtbufsize 10M -i "video=dev_realtime" -vcodec libx264 -preset veryfast -b 800k -maxrate 800k -bufsize 1600K -r 20 -f flv "rtmp://x.y"


Ещё заметил:
* если на выход установить файл (out.flv), то все четко идет.
* если поднять локально rtmp сервер (ffmpeg -y -f flv -listen 1 -i «rtmp://127.0.0.1:1935/app/live») и передавать на него, то тоже все четко идет
* udp://microsoft.com:666 - хорошо идет, буфер не переполняется

Удаленный сервер менял (от оборудования до провайдера), на сервере замерял битрейд - приходит четко 800kpbs. То есть успевает ffmpeg в сеть передавать?

Не пойму в чем затык! Вроде и на сервер успевает передавать своевременно, но и в тоже время на входе дропаются кадры. Ничего не пойму

Все гугления сводятся к бестолковым «увеличь rtbufsize»

UDP
Кажется баг в rtmp под windows. Помогают правки в реестре (DefaultReceiveWindow, DefaultSendWindow)
https://trac.ffmpeg.org/ticket/1604

 , , , ,

gobot
()

segfault и прочие read access

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

Есть вот такая чепуха, которая в треде парсит логи на предмет ошибок и прочего

//lambda - вызывается тредом, передает локальную переменную строку
[](std::string line){
  if (std::regex_search(line, std::regex(".*(some err).*"))) debug();
  if (std::regex_search(line, std::regex(".*(some err2).*"))) debug();
  if (std::regex_search(line, std::regex(".*(some err3).*"))) debug();
  //...
}


Когда тред каким-то образом убивается (в моем случае это в основном при выходе из программы) вылезают ошибки доступа к памяти. По call-stack вижу что где то далеко в std::regexp (где то в 18 хопе вверх от моего вызова регекса). Как я понимаю, в regex_search() переменная далее идет по цепочке вызовов и в ккакой то момент она удаляется. Вот как такое предотвратить? Ведь на момент вызова regex_search() переменная существовала? Как я понимаю это из-за того что переменная локальная? Когда тред завершается принудительно переменная удаляется.

Может быть сделать некий конвеер, чтобы не локальную переменную передавать? Как лучше сделать, чтобы избежать такого?

 ,

gobot
()

С++ удаляет локальные переменные

Узнал ужасную вещь. С++ удаляет локальные переменные.
Допустим создал я объект

Myclass xxx;
xxx.onready = func
xxx.start();

Создался объект, запустил start... Иии... Умер. Потом с++ запускает деструктор объекта. А мой колбек onready не дождется своего выхода.
Это нормально? Я же сам не удалял объект через delete. То есть получается компилятор сам за меня решает?

 

gobot
()

Выучил c++: как внедрить в бинарь свой код

Выучил я с++ и написал программу.

Теперь осталось запаковать ее и сделать первый выпуск.

Вот что я хочу: хочу, чтобы в бинарном файле можно было изменить строку. То есть бинарник будет как бы именным, с неким штампом, подписью, токеном. Я хочу типа регекспом искать в бинарнике некую строку и заменять ее на уникальную. Ну типа логина. Строка это будет например char name[10] = «holderxxxx». Вот мне этот holderxxxx нужно заменять на реальное значение, чтобы потом в коде вывести «привет name»

Как такое сделать?

 ,

gobot
()

C++ адрес подменяется

Продолжаю изучать с++

Process* ffplay = nullptr; //указатель в 0
ffplay = new Process("xxx"); //возвращается адрес  0x00000000003aa270 и заполняется память
ffplay->Start(); //тут запускается дочерний процес и также новый thread, который читает трубу процесса

delete ffplay; //освобождаю память
ffplay = nullptr; //указываю на адрес памяти 0x0000000000000000

//далее, в триде, проверяется что объект убит (это можно определить по свойствам объекта, например там id будет -12334214, а у созданого объекта 1..2..3...) и все поля либо NULL, ну в общем понятно. 

//трид успешно завершается, говорит что объект более не живучий и выхожу из цикла чтения. Ну либо когда труба закрыта

//стоит мне после этого создать новый объект на старый указатель
ffplay = new Process("xxx"); //тут снова 0x00000000003aa270

//то потом тред не завершается, потому что считает что объект все ещё живой. Это что получается, быстренько записали на старый адрес новые данные и тред даже не знает что ему подменили объект?

//если следом создать ещё один
Process *ffplay2 = new Process("xxx"); //тут адрес уже другой 0x000000000022d6b0


Как мне избежать такой подмены объекта в треде?

 , ,

gobot
()

RSS подписка на новые темы