波形の動画をRubyで作成


波形の動画をRubyで作成


音声が流れるのに合わせて波形が動く動画、よく見ると思いますよね。あれをRubyで作ってみたいと思います。果たしてRubyにその道具は揃っているのか……?

音声データの取得


素材はWikimedia Commonsで見付けた、槇原敬之の『ANSWER』にしてみましょう。このファイルはCC-BY 3.0で槇原敬之 Official Channelにより配布されています。

require "pathname"
require "open-uri"

src = URI("https://upload.wikimedia.org/wikipedia/commons/c/c5/ANSWER_TIME_TRAVELING_TOUR_2nd_Season.wav")
audio_path = Pathname("answer.wav")

unless audio_path.exist?
  audio_path.write src.read
end

これをAwaazで読み込みます。Awaazを選んだのはデータを数値計算ライブラリーのNumo::NArrayで返してくれるからで、諸々の計算を柔軟にかつ速くできるようにです。
require "numo/narray/alt"
require "awaaz"

waveform, sample_rate = Awaaz.load(audio_path.to_path)pp waveform # => Numo::DFloat#shape=[1,1287720]

shape の最初が 1 なのでモノラル、そして1287720サンプルあるようです。

AwaazはNumo::NArrayに依存しているのですが、今はNumo::NArrayその物はメンテされていなくて、Numo::NArray Alternativeを使いたいので、先に読み込んでおきます。

波形画像の作成


これを、動画の前に一旦画像にしてみましょう。 Numo::NArray の各要素をプロットすればそれっぽくなるはず。

1287720サンプルは多過ぎるので取り敢えず400サンプルぐらいにしておきます。また、冒頭だとあまり音がないので、適当に10000サンプル目ぐらいにしておきます。

w = 400
color = Numo::UInt8[255, 255, 0]

data = waveform[10000...(10000 + w)]
# DFloat -> UInt8
# そのまま画像にするとy座標が正の場合は下に、負の場合は上にプロットされるけど、逆になって欲しいので1.0 - dataにしている
q_data = Numo::UInt8.cast((1.0 - data) * (255.0 / 2).round)
# q_dataをone-hot化:
# [0, 5, 1, 4, 2, 3]みたいな配列から
# [
#   [1, 0, 0, 0, 0, 0],
#   [0, 0, 0, 0, 0, 1],
#   [0, 1, 0, 0, 0, 0],
#   [0, 0, 0, 0, 1, 0],
#   [0, 0, 1, 0, 0, 0],
#   [0, 0, 0, 1, 0, 0],
# ]
# と、対応箇所だけ1で他は0という配列の配列を作る
# これを画面に見立てて1の所をプロットすれば波形になる筈
eye = Numo::UInt8.eye(256)
image = eye[true, q_data]
# 1だった所を色を持ったピクセルにする
image = image.expand_dims(2) * color

目で見て確認したいので、保存します。Magroを使うと、Numo::NArrayの配列を画像として保存できます。
require "magro"

Magro::IO.imsave "magro.png", image

線が荒いですが、一先ずそれっぽくはなったんではないでしょうか!?

線を繋げる


上は一つのx座標に対して一つのyをプロットしているので、yが連続していない時に飛び飛びになって荒く見えてしまいます。この端の間を補完してみましょう。「吴小林のラインアルゴリズム」なる物を使ってみます。

詳細は各自調べてもらうとして、実装は次のようになります。

def line_brightness(x0, y0, x1, y1)
  brightness = Numo::SFloat.zeros(256, x1.to_i - x0.to_i + 1)
  x0, y0, x1, y1 = x0.to_f, y0.to_f, x1.to_f, y1.to_f
  steep = (y1 - y0).abs > (x1 - x0).abs
  if steep
    x0, y0 = y0, x0
    x1, y1 = y1, x1
  end
  if x0 > x1
    x0, x1 = x1, x0
    y0, y1 = y1, y0
  end
  dx = x1 - x0
  dy = y1 - y0
  grad = dx == 0 ? 0.0 : dy/dx

  xend = x0.round
  yend = y0 + grad * (xend - x0)
  xgap = rfpart(x0 + 0.5)
  xpxl1 = xend.to_i
  ypxl1 = yend.floor.to_i

  if steep
    brightness[xpxl1,     ypxl1] = rfpart(yend) * xgap
    brightness[xpxl1 + 1, ypxl1] =  fpart(yend) * xgap
  else
    brightness[ypxl1,     xpxl1] = rfpart(yend) * xgap
    brightness[ypxl1 + 1, xpxl1] =  fpart(yend) * xgap
  end

  yi = yend + grad
  xend = x1.round
  yend = y1 + grad * (xend - x1)
  xgap = fpart(x1 + 0.5)
  xpxl2 = xend.to_i
  ypxl2 = yend.floor.to_i

  if steep
    brightness[xpxl2,     ypxl2] = rfpart(yend) * xgap
    brightness[xpxl2 + 1, ypxl2] =  fpart(yend) * xgap
  else
    brightness[ypxl2,     xpxl2] = rfpart(yend) * xgap
    brightness[ypxl2 + 1, xpxl2] =  fpart(yend) * xgap
  end

  (xpxl1 + 1).upto xpxl2 - 1 do |x|
    if steep
      brightness[x, yi.floor.to_i]     = rfpart(yi)
      brightness[x, yi.floor.to_i + 1] =  fpart(yi)
    else
      brightness[yi.floor.to_i, x]     = rfpart(yi)
      brightness[yi.floor.to_i + 1, x] =  fpart(yi)
    end
  end

  brightness
end

def fpart(x)
  x - x.floor
end

def rfpart(x)
  1.0 - fpart(x)
end

これを使って同じ箇所の画像を作ってみます。まずはこの関数を使って「明るさの行列」を作り、それに色を掛けてやることで色付きの滑らかな線にします。
y_data = (1.0 - data) * (255.to_f / 2)
coverage = Numo::SFloat.zeros(256, w)
(w - 1).times do |i|
  segment = line_brightness(0, y_data[i], 1, y_data[i + 1])
  coverage[true, i]     += segment[true, 0]
  coverage[true, i + 1] += segment[true, 1]
end
coverage[coverage > 1.0] = 1.0

image = coverage.expand_dims(2) * color
image = Numo::UInt8.cast(image.round)

Magro::IO.imsave "magro-lined.png", image

大分見易いですね!

動画を生成


RMagickに、複数の画像を登録してから保存すると動画にできる機能があるので、それを使います。 Magick::ImageList に画像を登録していって最後に #write を呼びます。

NDAV を使うと Numo::NArray から Magick::Image に変換できるので、上で作ったやり方で画像データを作り、変換して Magick::ImageList に登録します。

コードを書く前にちょっとチラ裏で計算しておきましょう。

  • fpsは25にする(RMagickの制約っぽい)
  • 一フレーム当たりの秒数 = 1 / fps = 0.04
  • 全音声をこの0.04秒間単位で分割して、その範囲を画像化し、それを連続させることで動画にする
  • 全秒数 = サンプル数 / サンプルレート
  • 全フレーム数 = 全秒数 * fps
  • 一フレーム当たりのサンプル数 = サンプルレート / fps
  • i フレーム目のサンプルは i * 一フレーム当たりのサンプル数 (オフセット)から 一フレーム当たりのサンプル数 - 1 まで
  • 幅400ピクセルにするので、↑のサンプルから間引いて400サンプルにする

一つ一つゆっくり確かめれば難しいことは無い筈です。頭の中だけで考えるより、コードを書きながらの方が理解しやすいかも。

require "rmagick"
require "ndav/magick/image"
require "ndav/numo/narray"

include NDAV::Converter

fps = 25
duration = waveform.shape[1].to_f / sample_rate
samples_per_frame = (sample_rate.to_f / fps).round
num_frames = (duration * fps).ceil
image_list = Magick::ImageList.new
num_frames.times do |i|
  start_frame = i * samples_per_frame
  end_frame = start_frame + samples_per_frame - 1
  # linspaceはstart_frameからend_frameまで、w個になるように間引いた際のインデックスの列を作る関数
  indices = Numo::Int32.cast(Numo::DFloat.linspace(start_frame, end_frame, w).round)
  # Numo::NArrayではインデックスの列(配列)でアクセスすると、そのインデックスにある値をまとめて取って来た配列を返す
  data = waveform[indices]
  y_data = (1.0 - data) * (255.to_f / 2)
  coverage = Numo::SFloat.zeros(256, w)
  (w - 1).times do |i|
    segment = line_brightness(0, y_data[i], 1, y_data[i + 1])
    coverage[true, i]     += segment[true, 0]
    coverage[true, i + 1] += segment[true, 1]
  end
  coverage[coverage > 1.0] = 1.0
  image = coverage.expand_dims(2) * color
  image = Numo::UInt8.cast(image.round)

  image_list << MagickImage(image)
end

image_list.write "rmagick.mp4"

それっぽくなったんではないでしょうか!?

動画と音声を合成


では上の画のみ動画と元のオーディオデータを合成して完成……としたいところですがRubyでそれは難しくて結局 ffmpeg コマンドを呼び出すことになります。勿論実用的にはそれでいいのですが、できればRubyでやりたいところ……GStreamergemを使ってやってみましょう。

パイプライン定義


GStreamerはマルチメディア用のパイプライン構築ができるライブラリーです。コードを見ながら説明します。

require "gstreamer"

fps = 30
duration = waveform.shape[1].to_f / sample_rate
samples_per_frame = (sample_rate.to_f / fps).round
num_frames = (duration * fps).ceil

pipeline = Gst.parse_launch(<<~EOP)
  mp4mux name=mux ! filesink location=gstreamer.mp4

  appsrc name=audiosrc format=time caps=audio/x-raw,format=F32LE,rate=#{sample_rate},channels=#{waveform.shape[0]},layout=interleaved
    ! audioconvert ! avenc_aac ! aacparse ! queue ! mux.

  appsrc name=videosrc format=time caps=video/x-raw,format=RGB,width=#{w},height=256,framerate=#{fps}/1
    ! videoconvert ! x264enc ! h264parse ! queue ! mux.
EOP

今回は音声付き動画を作ります。音声作成パイプラインと(画のみの)動画作成パイプラインを作って、二つを合流させます。上では三ブロックあり、最初が合流用パイプライン、次がオーディオ作成パイプライン、最後が動画作成パイプラインになっています。因みに、fpsにRMagickみたいな制約は無いので30に変えています。
appsrc name=audiosrc format=time caps=audio/x-raw,format=F32LE,rate=#{sample_rate},channels=#{waveform.shape[0]},layout=interleaved
    ! audioconvert ! avenc_aac ! aacparse ! queue ! mux.

は appsrc という特別なソース(Rubyコードでデータを生成するソース)から出発して、 ! で繋げた audioconvert (オーディオ変換の調整役)、 avenc_aac (MP4で使うためのAACオーディオにエンコード)、 aacparse (AACオーディオのパース)、 queue (キューに積む)と繋げたパイプラインです。最後に mux. (最後の . が大事)と書くことで、一行目の mp4mux に繋げるという意味になります。

因みに、オーディオファイルは元々あるのだから appsrc から流し込むのではなくてそのまま使えないのか? と思われると思いますが(僕は思いました)、WAVEファイルはそのままではMP4に入れられないのでAACに変換するパイプラインはどうせ作らないといけません。だったらまあ、どうせRubyでオーディオデータの処理もするのだから、Rubyから流し込もうかなと思った次第です。どちらでもいけます。

動画も同様です。雰囲気で読んでください。

最後が

mp4mux name=mux ! filesink location=gstreamer.mp4

となっており、二つのパイプラインを合流させてMP4動画にまとめます。 gstreamer.mp4 という名前でファイルに保存しています。

ごにょごにょとやってこのパイプラインを動かし、そこに appsrc からオーディオデータと画像データを流し込んでやれば動画にしてくれるというわけです。

パイプラインの開始と終了


GStreamerのパイプラインの動かし方です。Cライブラリーの薄いラッパーで、ちょっとRubyらしくないかも知れません。

# 開始状態にする
pipeline.set_state Gst::State::PLAYING

# オーディオと画像を流し込む処理

# EOSかエラーが届いたら……
pipeline.bus.timed_pop_filtered Gst::CLOCK_TIME_NONE, Gst::MessageType::EOS | Gst::MessageType::ERROR
# 終了状態にする
pipeline.set_state Gst::State::NULL

というのが開始と終了です。この間にデータを流し込む処理を書きます。
オーディオと画像の作成
audio_src = pipeline.get_by_name("audiosrc")
video_src = pipeline.get_by_name("videosrc")

frame_duration = Gst::SECOND / fps

num_frames.times do |i|
  start_frame = i * samples_per_frame
  end_frame = start_frame + samples_per_frame - 1
  indices = Numo::Int32.cast(Numo::DFloat.linspace(start_frame, end_frame, w).round)
  data = Numo::SFloat.cast(waveform[indices])
  y_data = (1.0 - data) * (255.to_f / 2)
  coverage = Numo::SFloat.zeros(256, w)
  (w - 1).times do |i|
    segment = line_brightness(0, y_data[i], 1, y_data[i + 1])
    coverage[true, i]     += segment[true, 0]
    coverage[true, i + 1] += segment[true, 1]
  end
  coverage[coverage > 1.0] = 1.0
  image = coverage.expand_dims(2) * color
  image = Numo::UInt8.cast(image.round)

  pts = i * frame_duration

  samples = Numo::SFloat.cast(waveform[0, start_frame..end_frame])
  audio_buf = Gst::Buffer.new(nil, samples.byte_size, nil)
  audio_buf.fill 0, samples.to_binary
  audio_buf.pts = pts
  audio_buf.duration = frame_duration
  audio_src.push_buffer audio_buf

  video_buf = Gst::Buffer.new(nil, image.byte_size, nil)
  video_buf.fill 0, image.to_binary
  video_buf.pts = pts
  video_buf.duration = frame_duration
  video_src.push_buffer video_buf
end

audio_src.end_of_stream
video_src.end_of_stream

前半はさっきやった画像の生成で、元のサンプルから、フレームごとに該当する秒数の箇所を使っています。

後半はオーディオと画像それぞれで Numo::NArray#to_binary で String にして、それを元にGStreamerのバッファーを組み立て、パイプラインに流し込んでいます。Numo::NArray -> GStreamerも簡単にできるといいのだけれど……。

これらをまとめるとこうなります。

require "gstreamer"

fps = 30
duration = waveform.shape[1].to_f / sample_rate
samples_per_frame = (sample_rate.to_f / fps).round
num_frames = (duration * fps).ceil

pipeline = Gst.parse_launch(<<~EOP)
  mp4mux name=mux ! filesink location=gstreamer.mp4

  appsrc name=audiosrc format=time caps=audio/x-raw,format=F32LE,rate=#{sample_rate},channels=#{waveform.shape[0]},layout=interleaved
    ! audioconvert ! avenc_aac ! aacparse ! queue ! mux.

  appsrc name=videosrc format=time caps=video/x-raw,format=RGB,width=#{w},height=256,framerate=#{fps}/1
    ! videoconvert ! x264enc ! h264parse ! queue ! mux.
EOP

pipeline.set_state Gst::State::PLAYING

audio_src = pipeline.get_by_name("audiosrc")
video_src = pipeline.get_by_name("videosrc")

frame_duration = Gst::SECOND / fps

num_frames.times do |i|
  start_frame = i * samples_per_frame
  end_frame = start_frame + samples_per_frame - 1
  indices = Numo::Int32.cast(Numo::DFloat.linspace(start_frame, end_frame, w).round)
  data = Numo::SFloat.cast(waveform[indices])
  y_data = (1.0 - data) * (255.to_f / 2)
  coverage = Numo::SFloat.zeros(256, w)
  (w - 1).times do |i|
    segment = line_brightness(0, y_data[i], 1, y_data[i + 1])
    coverage[true, i]     += segment[true, 0]
    coverage[true, i + 1] += segment[true, 1]
  end
  coverage[coverage > 1.0] = 1.0
  image = coverage.expand_dims(2) * color
  image = Numo::UInt8.cast(image.round)

  pts = i * frame_duration

  samples = Numo::SFloat.cast(waveform[0, start_frame..end_frame])
  audio_buf = Gst::Buffer.new(nil, samples.byte_size, nil)
  audio_buf.fill 0, samples.to_binary
  audio_buf.pts = pts
  audio_buf.duration = frame_duration
  audio_src.push_buffer audio_buf

  video_buf = Gst::Buffer.new(nil, image.byte_size, nil)
  video_buf.fill 0, image.to_binary
  video_buf.pts = pts
  video_buf.duration = frame_duration
  video_src.push_buffer video_buf
end

audio_src.end_of_stream
video_src.end_of_stream

pipeline.bus.timed_pop_filtered Gst::CLOCK_TIME_NONE, Gst::MessageType::EOS | Gst::MessageType::ERROR
pipeline.set_state Gst::State::NULL

波形の動画をRubyで作成

おお、それっぽい!

(音声入りのためリンク先でご視聴ください。)

Talk of AI in KDE sets the community ablaze


Graham sounds more and more like a grifter. Is KDE slowly doing the walk towards evil?

A proposal to make KDE an "AI-native" desktop has gone down like a house on fire: screams, flames, people running for safety. There may be no survivors.*

Last weekend was KDE's annual Akademy conference and it included a presentation proposing an AI-native KDE. We noted that it seemed likely to polarize the audience. It looks like this was a considerable understatement.

In the days since, a debate over proposed restrictions on LLM-assisted contributions descended into bans and a deleted thread. An outside campaign called for KDE to prohibit AI altogether, a GNOME developer proposed a similar policy for that project, and KDE developer Nate Graham apologized for his role in the uproar.

The Akademy talk was titled "A lovable, sovereign, AI-native KDE" and the slide deck [PDF] is now available. It ends by saying: "The question is not whether AI. It is how. You choose how much AI – and which."

It seems almost calculated to provoke an argument rather than invite discussion. We do not know if the authors intended this – we attempted to contact both of them, but they have not yet responded.

Graham opened a discussion on Invent, KDE's GitLab instance, about proposed restrictions on LLM-assisted contributions. Although we are not a member, we watched this with some interest over the weekend. It rapidly became heated. Moderators issued warnings, restricted further comments, and eventually removed the thread.

There is an archive of the discussion, but we warn you, it contains some highly offensive language, albeit censored by the member who quoted another member's tweets on X. As events unfolded, the participant who drew attention to the posts was banned first. The author of the offensive material was banned later after their identity was verified.

The discussion is gone, but the argument continues.

One response was an outside initiative called KDE for People, which called on the KDE project to adopt a No-AI policy. Around 250 people signed it before its organizers closed it to further signatures.

GNOME developer Jordan Petridis has also published The GNOME LLM Policy That I Want, proposing that LLMs be barred from creating or modifying anything submitted to GNOME or hosted on its infrastructure.

This mentions the recent ballot on AI usage in Debian. We reported on the developer referendum about a month ago, noting that the broad spread of anti-AI options in the ballot was likely to split the vote. (This likelihood was dismissed in the comments.) Well, as The Register's Asia-Pacific desk reported a few days later, Debian did not ban AI contributions.

Graham subsequently explained his involvement in a post titled KDE and AI, and you, and me. He opens by saying: "So I accidentally triggered an online shitstorm in the process of trying to craft a set of more restrictive LLM usage guidelines for KDE. Sorry about that."

He notes that the Akademy talk met "what I'm told was a fairly chilly reception" and that "the next day, a workshop was held about the topic, also receiving a chilly reception."

Every couple of years, the KDE project sets three goals for the next two years. Earlier this week, after Akademy, it chose its latest three: you can see them in the last column of the goal-setting Kanban board. The ones chosen are:


KDE for Enterprise and Deployments (Issue #5)

Better documentation (Issue #2)

Next Generation Styling for KDE (Issue #3)

We see no mention of AI in there. In context, that may come as a relief to parts of the community.

Bootnote

*A tip of the black Borsalino to the late great Terry Pratchett, for two different "house on fire" references we combined. ®

This entry was edited (today, 11:47 AM)

Kent Pitman about #Macsyma and other languages implemented in #lisp vs other languages #lispyGopherClimate


Peertube LiveChat Plugin

This entry was edited (today, 11:17 AM)

AlmaLinux Puts Software Certification in the Hands of Users


For the first time, there's a way to carry out software certification on AlmaLinux, and the hardware suite has been rewritten alongside it, with test results from either certification path landing in the same public catalog.

Don't worry about the cost to validate or the uptime of the machine itself. Certifications are free, and the hardware checks no longer require you to install the distro on your setup.
Validating, how?

In this particular situation, software certification is basically a listing plus the confirmations that follow it. A publisher adds the product and picks which major versions of AlmaLinux it runs on.

The confirmations come from the people running software on their own hardware across various AlmaLinux releases, though they will need to sign up for an account if they want to post their findings.

Hardware certification is the other half that got some attention.

The alma-certify tool has been rewritten, with the developers claiming it can now achieve sub-10 minute certification runs on most hardware.

Another improvement is that alma-certify doesn't require an AlmaLinux installation anymore because it can work off live media or from an installation already on the machine. There's also a new machine registration flow that makes use of QR codes.

If you didn't know, this tool records what's in the machine, all the way down to drivers and firmware, then starts up a bunch of short checks that decide whether it passes.

Those checks cover a lot of ground, starting from computation and memory errors, storage health, networking drivers, to kernel state, virtualization, GPU, and peripherals.

Tracking results

Everything ends up in the catalog, and each entry is a result anyone can analyze. It holds the systems, components, and software that have been validated, alongside the benchmark figures from the published test runs.

Every major AlmaLinux release is tracked on its own, so provenance can be proved, and everything in the catalog is easily searchable. You can even make use of the free, read-only API to collect data in bulk.

Jonathan Wright, the Infrastructure Lead for AlmaLinux, directed his attention toward potential testers, saying that:

Two things would make all of this worth it. A lot of people and organizations want proof that AlmaLinux runs on the hardware they already own before they’ll give it a try, and now they can get that proof themselves.

Every result that gets submitted makes the case to hardware and software vendors that supporting AlmaLinux officially is a low-effort thing to do.

So if you have hardware sitting in front of you, or software you rely on every day, go tell us that it works. Validations stack, so adding yours to something already listed helps just as much as being the first.

In the end, this will only work if vendors and individual users take the effort to run tests and manually post them on the portal.

Shunting locomotive hauls a ČD service to Košice, departing Čadca


This entry was edited (today, 9:31 AM)

Locomotive pushes train from Žilina


This entry was edited (today, 9:01 AM)

UG_NewColorsOfLight Gallery Video


A public engagement video explaining my process in making new colors of light and inviting the public to submit drawings for me to make with the new colors of neon tubing made during the residency. You can see my fiance Ali and I blow glass with Leckie Gassman and pull tubes with Ali and Leckie. You can hear me voiceover explaining the process as well as scenes of me mixing phosphor powder and a bit about that process. I end the video talking about neon bending and have some scenes from that process, using the hand pulled tubing to make a "SUBMIT DRAWING HERE" in new colors divided by syllables.
The neon made is used as a color sample for a public submission box on view at the Urbanglass gallery/ store (Agnes Varis Arts Center) in downtown Brooklyn. One lucky drawing will be chosen on August 20th, to be turned into neon using the new colors made during the residency. Submit your drawings in person at Urbanglass, or digitally here color.cccfl.co
This entry was edited (Friday, September 11, 2026, 10:54 PM)

Solus Linux Adopts Formal AI and LLM Contribution Policy


Solus Linux has announced a new policy on using AI and large language model tools in project contributions, explaining where these tools can and cannot be used.

The Solus team says developers can use AI to help with contributions, but they must take full responsibility for their work. Anyone submitting code or package changes needs to test them first. If AI was used, the commit should include an ‘Assisted-by LLM’ note. Only developers, not automated bots, can submit contributions.

“Contributions to Solus that were made with AI/LLM tools are allowed, as long as they follow our policy.”

Solus explains that the policy helps keep the operating system high-quality and easy to maintain. Since many people use Solus every day, contributors need to check and understand their submissions, not just share code made by AI.

However, the rules are stricter for written content. Solus does not allow any AI-generated or partly AI-generated material in its blog or official communications.

The team warns contributors not to hide their use of AI tools. If someone tries to cover up AI involvement, their work could be rejected, and they might be blocked from future contributions. Solus adds that the goal is to encourage open teamwork, not to watch every detail of how people work.

Solus says its new rules are based on the Budgie Desktop AI policy, which itself takes ideas from projects like the Linux kernel and Fedora. Still, they’re leaving the door open as the team also points out that this policy may change as AI tools become more common in software development.

For more details, see the official Solus announcement.

in reply to SocialistVibes01

I installed solus (along with a handful of other distros) during the last week, it seems decent enough, better than a lot of other distros, although were I to do it again I would probably forgo budgie for kde plasma. That being said, budgie does now seem like a very viable option.

But... my reason for distrohopping again was looking for viable alternatives to my main distro, ones that would (hopefully soon) come out with anti ai statements. Solus chose not to do that, so has now been deleted.

Linux Kernel Developers Consider Adding AGENTS.md To Help Guide AI/LLM Agents


This Week in Plasma: Akademy Special


The 2026 G20 Summit in Context


The Political and Economic History of the G20 Summit, with a focus on the financial track summit in Asheville this year.
g20avl.noblogs.org/
linktr.ee/WNCalignment
This entry was edited (Saturday, September 19, 2026, 7:46 PM)

Julian Fietkau - SciOp and decentralized research data rescue - FediDay2026


SciOp and decentralized research data rescue
ctalx.c-base.org/fediday-2026/…
This entry was edited (yesterday, 1:45 PM)

Marco Wähner - Against All Odds: The Fediverse from a Sociological Perspective - FediDay2026


Against All Odds: The Fediverse from a Sociological Perspective
ctalx.c-base.org/fediday-2026/…
This entry was edited (yesterday, 12:45 PM)

Paul Fuxjäger - Fediverse-Atmosphere Bridging - Current State and Future Developments - FediDay2026


Fediverse-Atmosphere Bridging - Current State and Future Developments
ctalx.c-base.org/fediday-2026/…
This entry was edited (yesterday, 2:15 AM)

Sandra Barthel - Digitale Abhängigkeiten sichtbar machen: parlamentarische Kontrolle & IFG - FediDay2026


Digitale Abhängigkeiten sichtbar machen: parlamentarische Kontrolle & IFG
ctalx.c-base.org/fediday-2026/…
This entry was edited (yesterday, 1:45 PM)

Thomas Kahle - Hochschulen im Fediverse: Ein Mastodon-Account macht noch keinen Sommer. - FediDay2026


Hochschulen im Fediverse: Ein Mastodon-Account macht noch keinen Sommer.
ctalx.c-base.org/fediday-2026/…
This entry was edited (yesterday, 11:15 AM)

Peter Mechels [cpt zzepposs] - FediDay2026


A Fantastic FediVariety Circus — And now: the report!
ctalx.c-base.org/fediday-2026/…
This entry was edited (yesterday, 7:45 AM)

Software freedom day @ HSBXL - 2026


Peertube LiveChat Plugin

This entry was edited (yesterday, 11:44 AM)

Google is closing down Android more and more, Netherlands move to Linux - Linux Weekly News


Try out Joplin, one of the best Open Source Note taking apps: joplinapp.org/?source=TheLinux…

Use code LINUXEXPERIMENT for 25% off your first billing cycle for Joplin Cloud

Grab a brand new laptop or desktop running Linux: tuxedocomputers.com/en#

👏 SUPPORT THE CHANNEL:
Get access to:
- a Daily Linux News show
- a weekly patroncast for more thoughts
- your name in the credits

YouTube: youtube.com/@thelinuxexp/join
Patreon: patreon.com/thelinuxexperiment

Or, you can donate whatever you want:
paypal.me/thelinuxexp
Liberapay: liberapay.com/TheLinuxExperime…

👕 GET TLE MERCH
Support the channel AND get cool new gear: the-linux-experiment.creator-s…

#linuxnews #linuxdesktop #linux

Timestamps
00:00 Intro
00:55 Sponsor: Joplin
02:24 Netherlands goes with NixOS
05:38 Android is less and less open source
08:09 GoogleBook OS introduced as a Linux based system
10:57 KDE's proposed AI policy leads to massive backlash
13:57 GNOME dev offers a "no AI at all" policy
16:08 KDE announces their 3 mains goals for 2027
18:04 SteamOS update brings many performance improvements
19:51 Linux kernel 7.4 should open files 39% faster
20:54 Ubuntu improves how the system behaves when out of memory
22:52 Valve introduces new low latency codec for game streaming
24:09 Ubuntu will update the kernel on a weekly basis
25:35 Cosmic 1.9 brings two new applications
27:41 reactOS now has a solid DirectX implementation
29:24 Sponsor: Tuxedo Computers

Links:

Netherlands goes with NixOS
itsfoss.com/news/netherlands-d…

Android is less and less open source
itsfoss.com/news/grapheneos-an…

GoogleBook OS introduced as a Linux based system
techradar.com/computing/laptop…

KDE's proposed AI policy leads to massive backlash
gamingonlinux.com/2026/09/kde-…
pointieststick.com/2026/09/23/…

GNOME dev offers a "no AI at all" policy
blogs.gnome.org/alatiera/2026/…

KDE announces their 3 mains goals for 2027
phoronix.com/news/KDE-Goals-To…

SteamOS update brings many performance improvements
gamingonlinux.com/2026/09/stea…

Linux kernel 7.4 should open files 39% faster
phoronix.com/news/Linux-7.4-Fa…

Ubuntu improves how the system behaves when out of memory
discourse.ubuntu.com/t/improvi…

Valve introduces new low latency codec for game streaming
steamcommunity.com/groups/home…

Ubuntu will update the kernel on a weekly basis
canonical.com/blog/acceleratin…

Cosmic 1.9 brings two new applications
linuxiac.com/cosmic-desktop-1-…

reactOS now has a solid DirectX implementation
github.com/reactos/reactos/pul…

This entry was edited (today, 2:31 PM)
in reply to The Linux Experiment

My next phone will be running PostMarketOS. These things Google is doing like requiring app developers to register with them if you are using Google Play services in order to install their apps and only releasing security patches in a quarterly timeframe instead of monthly like they used to makes me think that eventually Google is going to stop publishing AOSP entirely.

I'm not just going to wait around for that to happen. I'm going to be working on using the alternative and hopefully getting developers to start moving their apps over to PostMarketOS.

This entry was edited (yesterday, 12:53 PM)

BSOD


final edit: You want real logs instead? add this to your kernel command: drm.panic_screen=kmsg


Kinda funny, kinda neat.

I have no idea what the QR-code might reveal (I could not read it from this picture), so I pixelised it just to be sure.

FWIW I know exactly what happened and did not panic. To reproduce, boot your device with init=/bin/sh, then type exit.

CachyOS


The picture above is generated by Drm panic which is part of the kernel itself, or maybe a separate module. The data in the QR code is the kmsg log.

Not systemd, which wasn't running when that happened.

And it's been around for years; I guess I haven't had a kernel panic in a long time.

This entry was edited (today, 6:59 AM)

webfinger package for NodeJS


About 14 years ago, I created a webfinger package for NodeJS. At the time, NodeJS was only a few years old. I had created pump.io as a new social networking engine and the successor to StatusNet. I needed a client for webfinger lookup — the process of converting a user@domain.tld handle to a API endpoint for processing messages — and there wasn’t one for NodeJS, so I made it.

It is kind of an antique — very old callback-style code that has its own HTTP processing system. It supported the older version of Webfinger, RFC 6415, using XML for the data format. It also supported the (at that time) new Webfinger specification, RFC 7033.

Since its last release in 2013, version 0.4.2, I hadn’t touched the project. It’s just been languishing in the npm repository, squatting on the “webfinger” package name, and collecting dust. The Webfinger RFC was published, ActivityPub was standardized, and the Fediverse grew and grew, without a single change to the package.

I realized I was sitting on this package a couple of years, ago, and I’ve been wanting to get a new version out. This week, I just did it. I ripped out all the legacy support for RFC 6415, upgraded the tests to use the Node test runner, switched from callback style to async/await, changed to ESM modules, and changed the format to StandardJS.

I also added a little utility method, so it’s easier to look up links in the JRD file that is returned. Now, to get an ActivityPub actor, you just do this:

<div>const types = [</div><div>  &apos;application/activity+json&apos;,</div><div>  &apos;application/ld+json; profile="<a href="https://www.w3.org/ns/activitystreams"&apos" target="_blank" rel="nofollow noopener noreferrer" translate="no"><span class="invisible">https://www.</span><span class="ellipsis">w3.org/ns/activitystreams"&apo</span><span class="invisible">s</span></a>;</div><div>]</div><div></div><div>const actorId = (await webfinger(&apos;user1@foo.example&apos;)).link(&apos;self&apos;, types)?.href</div>

I think the dependencies are low enough that you can use this version of the library from browser apps, although I haven’t tried it yet.

Anyway, I published version 0.5.1 today. I hope it provides some value to other people working on Fediverse software.

Elena Rossini - FediDay2026


Reasons to be hopeful: success stories from the Fediverse this year
ctalx.c-base.org/fediday-2026/…
This entry was edited (Friday, September 25, 2026, 10:08 AM)

IA : le grand enfumage


Soutenez Blast, nouveau média indépendant : blast-info.fr/soutenir

L'IA va-t-elle résoudre tous nos problèmes ? C'est ce qu'essaient de nous faire croire les dirigeants des grosses entreprises tech qui la développent.
Pourtant, entre les bouleversements du marché du travail, le coût écologique des data centers, ou les manipulations politiques et la diffusion de fausses interventions, la réalité est beaucoup moins rose que les publicités qu'on nous vend.

Alors dans cette émission, Lou Welgryn et Théo Alves Da Costa, les dirigeants de l'association Data for Good, démontent quelques uns des mythes autour de l'intelligence artificielle, afin de garder le regard le plus lucide possible sur ces transformations majeures déjà en cours. Quels sont les enjeux de pouvoir qui se cachent derrière la course à l'intelligence artificielle ? Éléments de réponse dans cette émission pour Blast.

Avertissement : cette émission ne traite pas tous les enjeux autour de l'IA, il y en a beaucoup trop, qui seront très bientôt traités dans d'autres formats à Blast.

Journaliste : Salomé Saqué
Montage : Émilie Fortun, Sandra Perrin
Son : Baptiste Veilhan, Théo Duchesne
Graphisme : Morgane Sabouret, Margaux Simon
Production : Hicham Tragha
Directeur du développement des collaborations extérieures : Mathias Enthoven
Co-directrice de la rédaction : Soumaya Benaïssa
Directeur de la publication : Denis Robert

Le site : blast-info.fr/
Facebook : facebook.com/blastofficiel
Twitter : twitter.com/blast_france
Instagram : instagram.com/blastofficiel/
Mastodon : mamot.fr/web/@blast_info
Peertube : video.blast-info.fr/
Twitch : twitch.tv/blastinfo
Bluesky : bsky.app/profile/blast-info.fr

#IA
#Economie
#entretien

This entry was edited (Friday, September 25, 2026, 3:10 AM)

Lowering The Bar!


Join us tonight as we recount the hilarious story of the bar that .. that ... You just need to hear this one. Trust us. That, the Wheels of Woe, and more, tonight on Grunt Speak Live!

#TerrencePopp #Comedy #Redonkulas #GruntSpeak #TheLair

Use this form to contact us!
docs.google.com/forms/d/e/1FAI…

This entry was edited (Friday, September 25, 2026, 5:32 AM)

Linux Kernel Developers Consider Adding AGENTS.md To Help Guide AI/LLM Agents


Linux Kernel Developers Consider Adding AGENTS.md To Help...
phoronix.com/news/Linux-Consid…

Excess Ejaculation Linked to Chronic Indigestion


Did you know semen contains it and digestion requires it?
#zinc
#zinc
This entry was edited (Thursday, September 24, 2026, 4:26 PM)

F-Droid 2.0: A New Chapter for Android Freedom


No, KDE isn't turning into an AI desktop


Timestamps:

00:00​ Intro

00:36​ Sponsor: TuxCare

01:46​ KDE's AI policy

06:42​ Existing AI policies

10:06​ Going further on AI

12:58​ My stance on AI

17:05​ FOSS projects: yes or no to AI?

28:02​ Sponsor: Tuxedo Computer


No, KDE isn't turning into an AI desktop


Check out TuxCare's Endless LifeCycle Support for PostgreSQL 14 and more: tuxcare.com/endless-lifecycle-…

Grab a brand new laptop or desktop running Linux: tuxedocomputers.com/en#

👏 SUPPORT THE CHANNEL:
Get access to:
- a Daily Linux News show
- a weekly patroncast for more thoughts
- your name in the credits

YouTube: youtube.com/@thelinuxexp/join
Patreon: patreon.com/thelinuxexperiment

Or, you can donate whatever you want:
paypal.me/thelinuxexp
Liberapay: liberapay.com/TheLinuxExperime…

👕 GET TLE MERCH
Support the channel AND get cool new gear: the-linux-experiment.creator-s…

Timestamps:
00:00 Intro
00:36 Sponsor: TuxCare
01:46 KDE's AI policy
06:42 Existing AI policies
10:06 Going further on AI
12:58 My stance on AI
17:05 FOSS projects: yes or no to AI?
28:02 Sponsor: Tuxedo Computers

#linux #linuxdesktop #ai


⇧