上海实习生招聘,基础软件/嵌入式软件方向,有意留下联系方式沟通 要求: 1. 27 年毕业,会有编程考试 2. 有学校的要求,可以细聊 3. 实习工资挺好的 4. 要求实习 2 个月
项目是一个文章生成系统,想在系统中嵌入agent来实现自动的文章写作。 老板的意思是直接在某个服务器上部署一个hermes agent配置各种写作Skills,审查Skills,素材Skills,然后直接API调用这个hermes,每次写文章的时候调用一下(新开session),然后审查的时候再调用一下。但是我总觉得哪里不对,如果每天几百上千次的调用,这样是不是太重了? 各位佬有什么经验可以指点一下小弟? 2 个帖子 - 2 位参与者 阅读完整话题
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>FLAC 歌词嵌入 · LRCLib</title> <style> :root { --bg: #08080f; --surface: #111118; --surface2: #181820; --border: #222230; --text: #e0e0e8; --text2: #8888a0; --accent: #a78bfa; --accent2: #7c5cfc; --green: #34d399; --gold: #fbbf24; --radius: 16px; --radius-sm: 10px; --radius-xs: 8px; } * { margin: 0; padding: 0; box-sizing: border-box; } body { background: var(--bg); font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', system-ui, sans-serif; min-height: 100vh; display: flex; justify-content: center; padding: 28px 16px; color: var(--text); } .container { width: 100%; max-width: 960px; display: flex; flex-direction: column; gap: 18px; } .header { text-align: center; padding: 8px 0 4px; } .header h1 { font-size: 1.7rem; font-weight: 700; letter-spacing: -0.4px; background: linear-gradient(135deg, #a78bfa, #34d399); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .header .sub { font-size: 0.82rem; color: var(--text2); margin-top: 2px; } .card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 22px; } .card-label { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 1.5px; color: var(--text2); margin-bottom: 12px; font-weight: 600; } .drop-wrapper { position: relative; } .drop-wrapper input[type="file"] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; z-index: 2; } .drop-zone { background: var(--surface2); border: 2px dashed #2a2a3e; border-radius: var(--radius); padding: 32px 20px; text-align: center; transition: all 0.2s; pointer-events: none; } .drop-wrapper.drag-over .drop-zone { border-color: var(--accent); background: #1a1a28; box-shadow: 0 0 0 6px rgba(124, 92, 252, 0.15); } .drop-wrapper:hover .drop-zone { border-color: var(--accent); background: #1a1a28; box-shadow: 0 0 0 6px rgba(124, 92, 252, 0.06); } .drop-zone .dz-icon { font-size: 2.4rem; margin-bottom: 8px; opacity: 0.8; } .drop-zone .dz-title { font-weight: 600; font-size: 0.95rem; } .drop-zone .dz-hint { font-size: 0.78rem; color: var(--text2); margin-top: 4px; } .file-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; } .chip { display: inline-flex; align-items: center; gap: 6px; background: var(--surface2); border: 1px solid var(--border); padding: 6px 12px; border-radius: 20px; font-size: 0.8rem; font-family: 'SF Mono', 'Consolas', monospace; color: #c0c0d0; } .chip .chip-tag { font-size: 0.64rem; background: #1e1e30; color: var(--accent); padding: 2px 7px; border-radius: 10px; font-weight: 500; } .chip .chip-del { cursor: pointer; color: #666; font-weight: 700; font-size: 1rem; line-height: 1; margin-left: 2px; transition: color 0.15s; } .chip .chip-del:hover { color: #f87171; } .row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; } .row.mt { margin-top: 12px; } .input { flex: 1; min-width: 180px; padding: 11px 16px; border-radius: var(--radius-xs); border: 1px solid var(--border); background: var(--surface2); color: var(--text); font-size: 0.9rem; outline: none; font-family: inherit; transition: border-color 0.2s; } .input:focus { border-color: var(--accent); } .input::placeholder { color: #555; } .btn { padding: 10px 20px; border-radius: 24px; border: 1px solid var(--border); background: var(--surface2); color: var(--text); cursor: pointer; font-size: 0.85rem; font-weight: 600; transition: all 0.2s; white-space: nowrap; display: inline-flex; align-items: center; gap: 5px; font-family: inherit; letter-spacing: 0.2px; } .btn:hover { background: #222238; border-color: #444; } .btn-primary { background: var(--accent2); border-color: var(--accent2); color: #fff; box-shadow: 0 4px 18px rgba(124, 92, 252, 0.25); } .btn-primary:hover { background: #8f6fff; border-color: #8f6fff; box-shadow: 0 6px 24px rgba(124, 92, 252, 0.35); } .btn-sm { padding: 6px 14px; font-size: 0.76rem; border-radius: 18px; } .btn-xs { padding: 4px 10px; font-size: 0.7rem; border-radius: 14px; } .btn:disabled { opacity: 0.35; cursor: not-allowed; pointer-events: none; } .hint { font-size: 0.72rem; color: var(--text2); margin-top: 6px; font-style: italic; } .results-box { display: none; max-height: 280px; overflow-y: auto; margin-top: 10px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface2); } .results-box.open { display: block; } .result-row { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; cursor: pointer; transition: background 0.12s; gap: 10px; flex-wrap: wrap; } .result-row:hover { background: #1e1e2c; } .result-row+.result-row { border-top: 1px solid rgba(255, 255, 255, 0.03); } .result-row.selected { background: #1a1830; border-left: 3px solid var(--accent); } .result-info { flex: 1; min-width: 0; } .result-info .rtrack { font-weight: 600; font-size: 0.88rem; } .result-info .rartist { font-size: 0.76rem; color: var(--text2); } .result-meta { font-size: 0.7rem; color: #555; white-space: nowrap; } .empty { text-align: center; color: var(--text2); padding: 28px; font-size: 0.85rem; } .spinner-wrap { text-align: center; padding: 28px; color: var(--text2); display: flex; align-items: center; justify-content: center; gap: 8px; } .spinner { width: 16px; height: 16px; border: 2px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 0.7s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } .lyrics-panel { display: none; margin-top: 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; } .lyrics-panel.open { display: block; } .lyrics-top { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px; padding: 12px 16px; background: #14141e; border-bottom: 1px solid var(--border); } .lyrics-top .ltitle { font-weight: 700; font-size: 1rem; } .lyrics-top .lartist { color: var(--accent); font-size: 0.82rem; } .lyrics-top .lalbum { color: var(--text2); font-size: 0.76rem; } .tabs { display: flex; gap: 3px; flex-wrap: wrap; } .tab { padding: 5px 12px; border-radius: 16px; border: 1px solid var(--border); background: transparent; color: var(--text2); cursor: pointer; font-size: 0.72rem; font-weight: 500; transition: 0.2s; font-family: inherit; } .tab.on { background: var(--accent2); border-color: var(--accent2); color: #fff; } .lyrics-content { padding: 16px; max-height: 340px; overflow-y: auto; background: #0c0c16; font-family: 'SF Mono', 'Fira Code', 'Consolas', 'PingFang SC', monospace; font-size: 0.8rem; line-height: 1.75; white-space: pre-wrap; color: #c0c0d0; } .lyrics-content .hl-tag { color: var(--accent); font-weight: 600; } .lyrics-content .hl-idx { color: #666; } .lyrics-content .hl-time { color: var(--green); } .lyrics-content .hl-section { color: var(--gold); } .lyrics-content .hl-style { color: #60a5fa; } .check-row { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; padding: 10px 0; font-size: 0.76rem; color: var(--text2); } .check-row label { display: flex; align-items: center; gap: 5px; cursor: pointer; user-select: none; } .check-row input[type="checkbox"] { accent-color: var(--accent2); width: 15px; height: 15px; cursor: pointer; } .action-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; padding-top: 12px; border-top: 1px solid var(--border); } .tag-chips { display: flex; gap: 4px; flex-wrap: wrap; } .tag-chip { padding: 4px 10px; border-radius: 14px; border: 1px solid var(--border); background: transparent; color: var(--text2); cursor: pointer; font-size: 0.68rem; font-weight: 500; transition: 0.2s; user-select: none; font-family: inherit; } .tag-chip.on { background: var(--accent2); border-color: var(--accent2); color: #fff; } .toast { position: fixed; top: 16px; left: 50%; transform: translateX(-50%); padding: 10px 22px; border-radius: 24px; font-weight: 600; font-size: 0.82rem; z-index: 999; opacity: 0; pointer-events: none; transition: opacity 0.3s; letter-spacing: 0.2px; } .toast.show { opacity: 1; } .toast.ok { background: #065f46; color: #d1fae5; box-shadow: 0 8px 28px rgba(5, 150, 105, 0.3); } .toast.err { background: #7f1d1d; color: #fecaca; box-shadow: 0 8px 28px rgba(220, 38, 38, 0.3); } .footer-note { text-align: center; font-size: 0.7rem; color: #555; } ::-webkit-scrollbar { width: 4px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: #333; border-radius: 2px; } @media (max-width: 640px) { .row { flex-direction: column; align-items: stretch; } .btn { justify-content: center; } .action-row { flex-direction: column; align-items: stretch; } } </style> </head> <body> <div class="container"> <div class="header"> <h1>🎵 FLAC 歌词嵌入工具</h1> <div class="sub">LRCLib 歌词搜索 · Vorbis Comment 标签写入 · 元数据覆盖</div> </div> <div class="card"> <div class="card-label">📂 选择 FLAC 文件</div> <div class="drop-wrapper" id="dropWrapper"> <input type="file" id="fileInput" accept=".flac,audio/flac" multiple> <div class="drop-zone"> <div class="dz-icon">🎶</div> <div class="dz-title">点击选择或拖拽 FLAC 文件</div> <div class="dz-hint">支持批量 · 自动读取 TITLE / ARTIST / ALBUM 标签</div> </div> </div> <div class="file-chips" id="fileChips"></div> <div class="row mt"> <button class="btn btn-sm" id="clearFilesBtn" disabled>🗑 清空</button> <span style="font-size:0.76rem;color:var(--text2);" id="fileStatus">等待添加 FLAC…</span> </div> </div> <div class="card"> <div class="card-label">🔍 搜索歌词</div> <div class="row"> <input class="input" id="searchInput" placeholder="歌曲名 或「歌曲名 - 歌手名」" autocomplete="off"> <button class="btn btn-primary" id="searchBtn">搜索</button> <button class="btn btn-sm" id="directBtn">🎯 精确获取</button> </div> <div class="hint" id="autoFillHint"></div> <div class="results-box" id="resultsBox"> <div id="resultsList"></div> </div> </div> <div class="card" id="lyricsCard" style="display:none;"> <div class="lyrics-panel open" id="lyricsPreview"> <div class="lyrics-top"> <div> <span class="ltitle" id="songName">—</span> <span style="margin:0 5px;color:#555;">·</span> <span class="lartist" id="songArtist">—</span> <span style="margin:0 5px;color:#555;">·</span> <span class="lalbum" id="songAlbum">—</span> </div> <div class="tabs"> <button class="tab on" data-fmt="lrc">LRC</button> <button class="tab" data-fmt="srt">SRT</button> <button class="tab" data-fmt="ass">ASS</button> <button class="tab" data-fmt="vtt">VTT</button> </div> </div> <div class="lyrics-content" id="lyricsContent"></div> </div> <div class="check-row"> <span>🔧 写入时覆盖:</span> <label><input type="checkbox" id="ovTitle" checked> TITLE</label> <label><input type="checkbox" id="ovArtist" checked> ARTIST</label> <label><input type="checkbox" id="ovAlbum" checked> ALBUM</label> <span style="color:#555;font-size:0.68rem;">用 API 返回信息覆盖 FLAC 标签</span> </div> <div class="action-row"> <span style="font-size:0.72rem;color:var(--text2);font-weight:600;">歌词标签</span> <div class="tag-chips" id="tagChips"> <span class="tag-chip on" data-tag="LYRICS">LYRICS</span> <span class="tag-chip" data-tag="UNSYNCEDLYRICS">UNSYNCEDLYRICS</span> <span class="tag-chip" data-tag="LYRICS_LRC">LYRICS_LRC</span> <span class="tag-chip" data-tag="LYRICS_SRT">LYRICS_SRT</span> <span class="tag-chip" data-tag="LYRICS_ASS">LYRICS_ASS</span> <span class="tag-chip" data-tag="LYRICS_VTT">LYRICS_VTT</span> </div> <span style="flex:1;"></span> <button class="btn btn-primary" id="embedBtn" disabled>💾 写入并下载</button> </div> </div> <div class="footer-note">浏览器安全限制:通过下载生成新文件,原文件不被修改</div> </div> <div class="toast" id="toast"></div> <script> (function() { var DW = document.getElementById('dropWrapper'); var FI = document.getElementById('fileInput'); var FC = document.getElementById('fileChips'); var CFB = document.getElementById('clearFilesBtn'); var FST = document.getElementById('fileStatus'); var SI = document.getElementById('searchInput'); var SB = document.getElementById('searchBtn'); var DB = document.getElementById('directBtn'); var AFH = document.getElementById('autoFillHint'); var RB = document.getElementById('resultsBox'); var RL = document.getElementById('resultsList'); var LC = document.getElementById('lyricsCard'); var LCT = document.getElementById('lyricsContent'); var SN = document.getElementById('songName'); var SA = document.getElementById('songArtist'); var SAL = document.getElementById('songAlbum'); var EB = document.getElementById('embedBtn'); var OVT = document.getElementById('ovTitle'); var OVA = document.getElementById('ovArtist'); var OVAL = document.getElementById('ovAlbum'); var TO = document.getElementById('toast'); var TABS = document.querySelectorAll('.tab'); var TCHIPS = document.querySelectorAll('.tag-chip'); var files = []; var song = null; var fmt = 'lrc'; var tag = 'LYRICS'; var results = []; var selectedIdx = -1; var tt; function toast(m, e) { clearTimeout(tt); TO.textContent = m; TO.className = 'toast show ' + (e ? 'err' : 'ok'); tt = setTimeout(function() { TO.className = 'toast'; }, 2200); } function esc(s) { var d = document.createElement('div'); d.appendChild(document.createTextNode(s)); return d.innerHTML; } function p2(n) { return String(n).padStart(2, '0'); } function p3(n) { return String(n).padStart(3, '0'); } function readMeta(file, cb) { var r = new FileReader(); r.onload = function(e) { try { var b = e.target.result; var v = new DataView(b); if (b.byteLength < 4) return cb({ t: null, a: null, c: null, al: null }); if (String.fromCharCode(v.getUint8(0), v.getUint8(1), v.getUint8(2), v.getUint8(3)) !== 'fLaC') return cb({ t: null, a: null, c: null, al: null }); var o = 4, lb = false, t = null, a = null, c = null, al = null; while (o < b.byteLength && !lb) { if (o + 4 > b.byteLength) break; var h = v.getUint8(o); lb = (h & 0x80) !== 0; var bt = h & 0x7F; var bs = (v.getUint8(o + 1) << 16) | (v.getUint8(o + 2) << 8) | v.getUint8(o + 3); o += 4; if (bt === 4 && o + bs <= b.byteLength) { var bl = new Uint8Array(b, o, bs); var dec = new TextDecoder('utf-8'); if (bl.length >= 4) { var vl = bl[0] | (bl[1] << 8) | (bl[2] << 16) | (bl[3] << 24); var p = 4 + vl; if (p + 4 <= bl.length) { var nc = bl[p] | (bl[p + 1] << 8) | (bl[p + 2] << 16) | (bl[p + 3] << 24); p += 4; for (var i = 0; i < nc && p + 4 <= bl.length; i++) { var cl = bl[p] | (bl[p + 1] << 8) | (bl[p + 2] << 16) | (bl[p + 3] << 24); p += 4; if (p + cl > bl.length) break; var cs = dec.decode(bl.slice(p, p + cl)); p += cl; var ei = cs.indexOf('='); if (ei > 0) { var k = cs.substring(0, ei).toUpperCase().trim(); var val = cs.substring(ei + 1).trim(); if (k === 'TITLE' && !t) t = val; if (k === 'ARTIST' && !a) a = val; if (k === 'COMPOSER' && !c) c = val; if (k === 'ALBUM' && !al) al = val; } } } } break; } o += bs; } cb({ t: t, a: a, c: c, al: al }); } catch (x) { cb({ t: null, a: null, c: null, al: null }); } }; r.onerror = function() { cb({ t: null, a: null, c: null, al: null }); }; r.readAsArrayBuffer(file); } function autoFill() { if (files.length === 0) { AFH.textContent = ''; return; } var t = files[0].t || ''; var a = files[0].a || files[0].c || ''; if (t) { var ft = t; if (a) ft += ' - ' + a; SI.value = ft; AFH.textContent = '📋 已从 FLAC 标签自动填充:' + ft; } else { AFH.textContent = '⚠️ 未找到 TITLE 标签,请手动输入'; } } function updateFiles() { FC.innerHTML = ''; if (files.length === 0) { CFB.disabled = true; FST.textContent = '等待添加 FLAC…'; EB.disabled = true; AFH.textContent = ''; } else { CFB.disabled = false; FST.textContent = files.length + ' 个 FLAC 文件'; if (song) EB.disabled = false; for (var i = 0; i < files.length; i++) { var f = files[i]; var el = document.createElement('span'); el.className = 'chip'; var h = '🎵 ' + esc(f.file.name); if (f.t) h += ' <span class="chip-tag">' + esc(f.t) + '</span>'; h += ' <span class="chip-del" data-idx="' + i + '">×</span>'; el.innerHTML = h; FC.appendChild(el); } var dels = FC.querySelectorAll('.chip-del'); for (var d = 0; d < dels.length; d++) { dels[d].onclick = function(e) { e.stopPropagation(); var idx = parseInt(this.getAttribute('data-idx'), 10); files.splice(idx, 1); updateFiles(); autoFill(); }; } } } function addFiles(fileList) { var only = []; for (var i = 0; i < fileList.length; i++) { if (!fileList[i].name.toLowerCase().endsWith('.flac')) continue; var dup = false; for (var j = 0; j < files.length; j++) { if (files[j].file.name === fileList[i].name && files[j].file.size === fileList[i].size && files[j].file.lastModified === fileList[i].lastModified) { dup = true; break; } } if (!dup) only.push(fileList[i]); } if (only.length === 0) { if (fileList.length > 0) toast('请选择 .flac 文件', true); return; } FST.textContent = '🔍 读取元数据…'; var done = 0; var total = only.length; function handleOne(f, meta) { files.push({ file: f, t: meta.t, a: meta.a, c: meta.c, al: meta.al }); done++; if (done >= total) { updateFiles(); autoFill(); toast('✅ 已添加 ' + total + ' 个 FLAC 文件'); if (files.length > 0 && SI.value.trim()) doSearch(SI.value); } } for (var k = 0; k < only.length; k++) { (function(fileRef) { readMeta(fileRef, function(meta) { handleOne(fileRef, meta); }); })(only[k]); } } function handleFileSelect(fileList) { if (fileList && fileList.length) { addFiles(fileList); } } FI.addEventListener('change', function(e) { handleFileSelect(e.target.files); FI.value = ''; }); DW.addEventListener('dragover', function(e) { e.preventDefault(); e.stopPropagation(); DW.classList.add('drag-over'); }); DW.addEventListener('dragleave', function(e) { e.preventDefault(); e.stopPropagation(); DW.classList.remove('drag-over'); }); DW.addEventListener('drop', function(e) { e.preventDefault(); e.stopPropagation(); DW.classList.remove('drag-over'); if (e.dataTransfer.files && e.dataTransfer.files.length) { handleFileSelect(e.dataTransfer.files); } }); CFB.addEventListener('click', function() { files = []; updateFiles(); autoFill(); toast('🧹 已清空'); }); function apiSearch(q) { return fetch('https://lrclib.net/api/search?q=' + encodeURIComponent(q)).then(function(r) { if (!r.ok) throw new Error('搜索失败'); return r.json(); }); } function apiGet(t, a) { return fetch('https://lrclib.net/api/get?track_name=' + encodeURIComponent(t) + '&artist_name=' + encodeURIComponent(a)).then(function(r) { if (!r.ok) throw new Error('获取失败'); return r.text(); }).then(function(t) { if (!t) throw new Error('未找到'); return JSON.parse(t); }); } function parseLrc(sl) { var items = []; if (!sl) return items; var re = /\[(\d{2}):(\d{2})\.(\d{2,3})\]\s*(.*)/g, m; while ((m = re.exec(sl)) !== null) { var ms = m[3].length === 2 ? parseInt(m[3], 10) * 10 : parseInt(m[3], 10); items.push({ tm: parseInt(m[1]) * 60000 + parseInt(m[2]) * 1000 + ms, tx: (m[4] || '').trim() }); } return items; } function msLrc(ms) { var mn = Math.floor(ms / 60000); return '[' + p2(mn) + ':' + p2(Math.floor((ms % 60000) / 1000)) + '.' + p2(Math.floor((ms % 1000) / 10)) + ']'; } function msSrt(ms) { var h = Math.floor(ms / 3600000); return p2(h) + ':' + p2(Math.floor((ms % 3600000) / 60000)) + ':' + p2(Math.floor((ms % 60000) / 1000)) + ',' + p3(ms % 1000); } function msAss(ms) { var h = Math.floor(ms / 3600000); return h + ':' + p2(Math.floor((ms % 3600000) / 60000)) + ':' + p2(Math.floor((ms % 60000) / 1000)) + '.' + p2(Math.floor((ms % 1000) / 10)); } function msVtt(ms) { var h = Math.floor(ms / 3600000); return p2(h) + ':' + p2(Math.floor((ms % 3600000) / 60000)) + ':' + p2(Math.floor((ms % 60000) / 1000)) + '.' + p3(ms % 1000); } function genLRC(s) { var it = parseLrc(s.syncedLyrics); var l = []; l.push('[ti:' + (s.trackName || '') + ']'); l.push('[ar:' + (s.artistName || '') + ']'); if (s.albumName) l.push('[al:' + s.albumName + ']'); if (s.duration) { var m = Math.floor(s.duration / 60); l.push('[length:' + p2(m) + ':' + p2(Math.floor(s.duration % 60)) + ']'); } l.push(''); if (it.length) { for (var i = 0; i < it.length; i++) l.push(msLrc(it[i].tm) + (it[i].tx || '♪')); } else if ( s.plainLyrics) { var pl = s.plainLyrics.split('\n'); for (var j = 0; j < pl.length; j++) l.push(pl[j] .trim()); } return l.join('\n'); } function genSRT(s) { var it = parseLrc(s.syncedLyrics); if (!it.length) return s.plainLyrics ? '1\n00:00:00,000 --> 00:03:00,000\n' + s.plainLyrics.trim() + '\n' : ''; var l = []; for (var i = 0; i < it.length; i++) { var nx = it[i + 1], em = nx ? nx.tm : it[i].tm + 3000; l.push(String(i + 1)); l.push(msSrt(it[i].tm) + ' --> ' + msSrt(em)); l.push(it[i].tx || '♪'); l.push(''); } return l.join('\n').trim(); } function genASS(s) { var it = parseLrc(s.syncedLyrics); var l = []; l.push('[Script Info]'); l.push('Title: ' + (s.trackName || 'Unknown')); l.push('Original Script: ' + (s.artistName || 'Unknown')); l.push('ScriptType: v4.00+'); l.push('Collisions: Normal'); l.push('PlayDepth: 0'); l.push(''); l.push('[V4+ Styles]'); l.push( 'Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding'); l.push( 'Style: Default,Microsoft YaHei,36,&H00FFFFFF,&H000000FF,&H00000000,&H80000000,-1,0,0,0,100,100,0,0,1,2,1,2,30,30,30,1'); l.push(''); l.push('[Events]'); l.push('Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text'); if (it.length) { for (var i = 0; i < it.length; i++) { var nx = it[i + 1], em = nx ? nx.tm : it[i].tm + 3000; l.push('Dialogue: 0,' + msAss(it[i].tm) + ',' + msAss(em) + ',Default,,0,0,0,,' + (it[i].tx || '♪').replace(/\n/g, '\\N')); } } else if (s.plainLyrics) { var pl = s.plainLyrics.split('\n').filter(function(x) { return x.trim(); }); var dur = (s.duration || 180) * 1000; var each = Math.floor(dur / Math.max(pl.length, 1)); for (var j = 0; j < pl.length; j++) l.push('Dialogue: 0,' + msAss(j * each) + ',' + msAss(j * each + each) + ',Default,,0,0,0,,' + pl[j].trim().replace(/\n/g, '\\N')); } return l.join('\n'); } function genVTT(s) { var it = parseLrc(s.syncedLyrics); var l = []; l.push('WEBVTT'); l.push(''); if (it.length) { for (var i = 0; i < it.length; i++) { var nx = it[i + 1], em = nx ? nx.tm : it[i].tm + 3000; l.push(msVtt(it[i].tm) + ' --> ' + msVtt(em)); l.push(it[i].tx || '♪'); l.push(''); } } else if (s.plainLyrics) { var pl = s.plainLyrics.split('\n').filter(function(x) { return x.trim(); }); var dur = (s.duration || 180) * 1000; var each = Math.floor(dur / Math.max(pl.length, 1)); for (var j = 0; j < pl.length; j++) { l.push(msVtt(j * each) + ' --> ' + msVtt(j * each + each)); l.push(pl[j].trim()); l.push(''); } } return l.join('\n').trim(); } function getFmt(f, s) { if (!s) return ''; if (f === 'lrc') return genLRC(s); if (f === 'srt') return genSRT(s); if (f === 'ass') return genASS(s); if (f === 'vtt') return genVTT(s); return ''; } function hlHtml(f, s) { var raw = getFmt(f, s); if (!raw) return '<span style="color:#555;">暂无内容</span>'; var e = esc(raw); if (f === 'lrc') { e = e.replace(/^(\[ti:.*\]|\[ar:.*\]|\[al:.*\]|\[length:.*\])$/gm, '<span class="hl-tag">$1</span>'); e = e.replace(/^(\[\d{2}:\d{2}\.\d{2}\])/gm, '<span class="hl-tag">$1</span>'); } else if (f === 'srt') { e = e.replace(/^(\d+)$/gm, '<span class="hl-idx">$1</span>'); e = e.replace(/^(\d{2}:\d{2}:\d{2},\d{3} --> \d{2}:\d{2}:\d{2},\d{3})$/gm, '<span class="hl-time">$1</span>'); } else if (f === 'ass') { e = e.replace(/^(\[.*\])$/gm, '<span class="hl-section">$1</span>'); e = e.replace(/^(Style:.*)$/gm, '<span class="hl-style">$1</span>'); e = e.replace(/^(Format:.*)$/gm, '<span class="hl-style">$1</span>'); } else if (f === 'vtt') { e = e .replace(/^(WEBVTT)$/gm, '<span class="hl-section">$1</span>'); e = e.replace(/^(\d{2}:\d{2}:\d{2}\.\d{3} --> \d{2}:\d{2}:\d{2}\.\d{3})$/gm, '<span class="hl-time">$1</span>'); } return e; } function renderSong(s) { song = s; SN.textContent = s.trackName || '未知'; SA.textContent = s.artistName || '未知'; SAL.textContent = s.albumName ? '💿 ' + s.albumName : ''; LC.style.display = 'block'; if (files.length > 0) EB.disabled = false; updateLyrics(); LC.scrollIntoView({ behavior: 'smooth', block: 'center' }); } function updateLyrics() { LCT.innerHTML = hlHtml(fmt, song); } for (var t = 0; t < TABS.length; t++) { TABS[t].addEventListener('click', function() { for (var i = 0; i < TABS.length; i++) TABS[i].classList.remove('on'); this.classList.add('on'); fmt = this.getAttribute('data-fmt'); updateLyrics(); }); } for (var c = 0; c < TCHIPS.length; c++) { TCHIPS[c].addEventListener('click', function() { for (var i = 0; i < TCHIPS.length; i++) TCHIPS[i].classList.remove('on'); this.classList.add('on'); tag = this.getAttribute('data-tag'); }); } function doSearch(q) { if (!q || !q.trim()) { toast('请输入关键词', true); return; } results = []; selectedIdx = -1; RL.innerHTML = '<div class="spinner-wrap"><span class="spinner"></span>搜索中…</div>'; RB.classList.add('open'); apiSearch(q.trim()).then(function(rs) { results = rs; if (!rs.length) { RL.innerHTML = '<div class="empty">😕 未找到匹配的歌曲</div>'; return; } var h = ''; for (var i = 0; i < rs.length; i++) { var r = rs[i]; h += '<div class="result-row" data-idx="' + i + '">'; h += '<div class="result-info"><div class="rtrack">' + esc(r.trackName || r.name || '未知') + '</div><div class="rartist">' + esc(r.artistName || '未知') + '</div></div>'; h += '<div class="result-meta">' + fdur(r.duration) + '</div>'; h += '<button class="btn btn-xs pick-btn" data-idx="' + i + '">选择</button>'; h += '</div>'; } RL.innerHTML = h; bindResults(); }).catch(function(err) { RL.innerHTML = '<div class="empty">❌ ' + esc(err.message) + '</div>'; }); } function bindResults() { var rows = RL.querySelectorAll('.result-row'); for (var j = 0; j < rows.length; j++) { (function(idx) { rows[j].addEventListener('click', function(e) { if (e.target.closest('.pick-btn')) return; loadResult(idx); }); })(j); } var btns = RL.querySelectorAll('.pick-btn'); for (var k = 0; k < btns.length; k++) { (function(idx) { btns[k].addEventListener('click', function(e) { e.stopPropagation(); loadResult(idx); }); })(k); } } function loadResult(idx) { var s = results[idx]; if (!s) return; selectedIdx = idx; var tn = s.trackName || s.name; var an = s.artistName || ''; var rows = RL.querySelectorAll('.result-row'); for (var i = 0; i < rows.length; i++) { rows[i].classList.remove('selected'); rows[i].style.opacity = '0.4'; } var tgt = RL.querySelector('[data-idx="' + idx + '"]'); if (tgt) { tgt.classList.add('selected'); tgt.style.opacity = '1'; } apiGet(tn, an).then(function(d) { renderSong(d); for (var j = 0; j < rows.length; j++) rows[j].style.opacity = '1'; }).catch(function(err) { toast('❌ ' + err.message, true); for (var j = 0; j < rows.length; j++) rows[j].style.opacity = '1'; selectedIdx = -1; }); } function fdur(s) { if (!s && s !== 0) return ''; var m = Math.floor(s / 60); return m + ':' + p2(Math.floor(s % 60)); } SB.addEventListener('click', function() { doSearch(SI.value); }); SI.addEventListener('keydown', function(e) { if (e.key === 'Enter') doSearch(SI.value); }); DB.addEventListener('click', function() { var q = SI.value.trim(); if (!q) { toast('请输入「歌曲名 - 歌手名」', true); return; } var seps = [' - ', '-', ' – ', '–', ' | ', '|', ':', ':']; var tk = '', ar = ''; for (var i = 0; i < seps.length; i++) { if (q.indexOf(seps[i]) !== -1) { var pts = q.split(seps[i]); tk = pts[0].trim(); ar = pts.slice(1).join(seps[i]).trim(); break; } } if (!tk) { tk = prompt('歌曲名:', q); if (!tk) return; ar = prompt('歌手名(可选):', '') || ''; } results = []; selectedIdx = -1; RL.innerHTML = '<div class="spinner-wrap"><span class="spinner"></span>获取中…</div>'; RB.classList.add('open'); apiGet(tk, ar).then(function(d) { results = [d]; selectedIdx = 0; RL.innerHTML = '<div class="result-row selected" data-idx="0" style="opacity:1;"><div class="result-info"><div class="rtrack">' + esc(d.trackName || d.name || '未知') + '</div><div class="rartist">' + esc(d.artistName || '未知') + '</div></div><div class="result-meta">' + fdur(d.duration) + '</div></div>'; renderSong(d); }).catch(function(err) { RL.innerHTML = '<div class="empty">❌ ' + esc(err.message) + '</div>'; toast('❌ ' + err.message, true); }); }); function readBlocks(ab) { var v = new DataView(ab); var b = ab; if (b.byteLength < 4) throw new Error('太小'); if (String.fromCharCode(v.getUint8(0), v.getUint8(1), v.getUint8(2), v.getUint8(3)) !== 'fLaC') throw new Error( '非FLAC'); var bl = []; var o = 4, lb = false; while (o < b.byteLength && !lb) { if (o + 4 > b.byteLength) break; var h = v.getUint8(o); lb = (h & 0x80) !== 0; var bt = h & 0x7F; var bs = (v.getUint8(o + 1) << 16) | (v.getUint8(o + 2) << 8) | v.getUint8(o + 3); var st = o; o += 4; bl.push({ type: bt, last: lb, ho: st, dto: o, size: bs }); o += bs; } return { blocks: bl, buf: b }; } function parseVC(bi, buf) { var bl = new Uint8Array(buf, bi.dto, bi.size); var dec = new TextDecoder('utf-8'); if (bl.length < 4) return { cmts: [] }; var vl = bl[0] | (bl[1] << 8) | (bl[2] << 16) | (bl[3] << 24); var p = 4 + vl; if (p + 4 > bl.length) return { cmts: [] }; var nc = bl[p] | (bl[p + 1] << 8) | (bl[p + 2] << 16) | (bl[p + 3] << 24); p += 4; var cmts = []; for (var i = 0; i < nc; i++) { if (p + 4 > bl.length) break; var cl = bl[p] | (bl[p + 1] << 8) | (bl[p + 2] << 16) | (bl[p + 3] << 24); p += 4; if (p + cl > bl.length) break; cmts.push(dec.decode(bl.slice(p, p + cl))); p += cl; } return { cmts: cmts }; } function buildVC(cmts, isLast) { var enc = new TextEncoder(); var vb = new Uint8Array(4); var cb = new Uint8Array(4); cb[0] = cmts.length & 0xFF; cb[1] = (cmts.length >> 8) & 0xFF; cb[2] = (cmts.length >> 16) & 0xFF; cb[3] = (cmts.length >> 24) & 0xFF; var arrs = []; for (var i = 0; i < cmts.length; i++) { var ed = enc.encode(cmts[i]); var lb = new Uint8Array(4); lb[0] = ed.length & 0xFF; lb[1] = (ed.length >> 8) & 0xFF; lb[2] = (ed.length >> 16) & 0xFF; lb[3] = (ed.length >> 24) & 0xFF; arrs.push(lb); arrs.push(ed); } var tp = 8; for (var j = 0; j < arrs.length; j++) tp += arrs[j].length; var bh = new Uint8Array(4); bh[0] = 4; if (isLast) bh[0] |= 0x80; bh[1] = (tp >> 16) & 0xFF; bh[2] = (tp >> 8) & 0xFF; bh[3] = tp & 0xFF; var res = new Uint8Array(4 + tp); res.set(bh, 0); var off = 4; res.set(vb, off); off += 4; res.set(cb, off); off += 4; for (var k = 0; k < arrs.length; k++) { res.set(arrs[k], off); off += arrs[k].length; } return res; } function embed(file, lc, tn, sm, ov, cb) { var r = new FileReader(); r.onload = function(e) { try { var info = readBlocks(e.target.result); var bl = info.blocks; var buf = info.buf; var vi = -1; for (var i = 0; i < bl.length; i++) { if (bl[i].type === 4) { vi = i; break; } } var nc = []; var tu = tn.toUpperCase(); var pk = [tu]; if (ov.title) pk.push('TITLE'); if (ov.artist) pk.push('ARTIST'); if (ov.album) pk.push('ALBUM'); if (vi >= 0) { var parsed = parseVC(bl[vi], buf); for (var j = 0; j < parsed.cmts.length; j++) { var eq = parsed.cmts[j].indexOf('='); if (eq > 0) { var key = parsed.cmts[j].substring(0, eq).toUpperCase().trim(); if (pk.indexOf( key) === -1) nc.push(parsed.cmts[j]); } else nc.push(parsed.cmts[j]); } } nc.push(tu + '=' + lc); if (ov.title && sm.trackName) nc.push('TITLE=' + sm.trackName); if (ov.artist && sm.artistName) nc.push('ARTIST=' + sm.artistName); if (ov.album && sm.albumName) nc.push('ALBUM=' + sm.albumName); var isLast = (vi >= 0) ? bl[vi].last : false; var nb = buildVC(nc, isLast); var parts = []; if (vi >= 0) { parts.push(new Uint8Array(buf, 0, bl[vi].ho)); parts.push(nb); parts.push(new Uint8Array(buf, bl[vi].dto + bl[vi].size)); } else { var si = -1; for (var k = 0; k < bl.length; k++) { if (bl[k].type === 0) { si = k; break; } } if (si >= 0) { var sho = bl[si].ho; var sa = bl[si].dto + bl[si].size; parts.push(new Uint8Array(buf, 0, sho)); var sh = new Uint8Array(buf, sho, 4); sh[0] = sh[0] & 0x7F; parts.push(sh); parts.push(new Uint8Array(buf, bl[si].dto, bl[si].size)); parts.push(nb); parts.push(new Uint8Array(buf, sa)); } else { parts.push(new Uint8Array(buf, 0, 4)); parts.push(nb); parts.push(new Uint8Array(buf, 4)); } } var tl = 0; for (var p = 0; p < parts.length; p++) tl += parts[p].length; var result = new Uint8Array(tl); var off = 0; for (var q = 0; q < parts.length; q++) { result.set(parts[q], off); off += parts[q].length; } cb(null, new Blob([result], { type: 'audio/flac' })); } catch (x) { cb(x); } }; r.onerror = function() { cb(new Error('读取失败')); }; r.readAsArrayBuffer(file); } EB.addEventListener('click', function() { if (!files.length) { toast('请先添加 FLAC 文件', true); return; } if (!song) { toast('请先选择歌词', true); return; } var lc = getFmt(fmt, song); if (!lc.trim()) { toast('当前格式无内容', true); return; } var ov = { title: OVT.checked, artist: OVA.checked, album: OVAL.checked }; EB.disabled = true; CFB.disabled = true; var extra = []; if (ov.title) extra.push('TITLE'); if (ov.artist) extra.push('ARTIST'); if (ov.album) extra.push('ALBUM'); var em = extra.length ? ' + 覆盖 ' + extra.join('/') : ''; toast('⏳ 正在写入 ' + files.length + ' 个文件' + em + '…'); var ok = 0, fl = 0; function next(idx) { if (idx >= files.length) { EB.disabled = false; CFB.disabled = false; if (fl === 0) toast('🎉 成功!已下载 ' + ok + ' 个 FLAC 文件' + em); else toast('⚠️ ' + ok + ' 成功, ' + fl + ' 失败', true); return; } embed(files[idx].file, lc, tag, song, ov, function(err, blob) { if (err) { fl++; console.error(err); } else { var url = URL.createObjectURL(blob); var a = document.createElement('a'); a.href = url; a.download = files[idx].file.name; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); ok++; } setTimeout(function() { next(idx + 1); }, 200); }); } next(0); }); updateFiles(); SI.focus(); })(); </script> </body> </html> 歌词搜索、标签写入和元数据覆盖一次性搞定 2 个帖子 - 2 位参与者 阅读完整话题
主要做视觉、嵌入式、ROS,佬友们有什么推荐的电脑和配置吗? 最好性价比高一些,初创公司。 5 个帖子 - 5 位参与者 阅读完整话题
嵌入式硬件工程师 薪资范围 12K-20K (能力优秀可面议) 工作地点 杭州 岗位职责 负责 DTU 、LoRa/4G 网关等物联网产品的硬件设计与开发; 负责产品原理图设计、PCB Layout 、器件选型、BOM 整理及硬件调试; 负责 LoRa 、4G Cat.1 、以太网等通信接口设计与调试; 负责 STM32 系列 MCU 外围电路设计与软硬件联调; 需要有一定的嵌入式软件开发能力; 输出设计文档、测试文档及生产资料。 任职要求 必须具备 2 年以上嵌入式硬件开发经验; 熟练使用 Altium Designer 进行原理图设计及 PCB 设计; 熟悉 STM32 、APM32 等 MCU 硬件设计; 熟悉 RS485 、UART 、SPI 、IIC 、CAN 等接口电路; 熟悉开关电源、电源管理、电磁兼容设计; 能独立完成产品从需求到样机的开发工作; 能熟练使用示波器、逻辑分析仪、万用表等调试工具。 加分项(重点关注) 满足任意两项以上优先录用: 做过 DTU 产品; 做过 LoRa 网关或 LoRa 节点; 做过 4G Cat.1 / NB-IoT 产品; 有软硬件独立开发经验; 能编写 STM32 驱动及简单业务逻辑代码; 使用过 RTOS ( freeRTOS\Threadx\RT-Thread)等。 不太匹配的方向 以下背景可作为参考,但优先级较低: 家电控制板 消费电子 PCB Layout 纯 EMC 工程师 纯测试工程师 纯软件工程师 电机控制工程师 无量产经验的应届生 关于团队/公司 众流是一家专注于台球行业数字化服务的科技企业,致力于通过软件系统与智能硬件的深度融合,推动台球门店经营管理的数字化升级。 目前,众流已为全国大量台球门店提供经营管理系统、会员系统、营销系统及数字化运营服务。随着业务发展,公司正在持续投入智能硬件产品研发,打造覆盖门店经营全场景的智能控制体系。 我们的研发方向包括: 台球桌智能控制系统 门店设备联网系统 4G/LoRa 通信设备 数据采集终端 边缘控制网关 灯光控制系统 自助营业设备 无人值守解决方案 未来,我们希望实现: 球桌、灯光、空调、门禁、收银、会员系统、经营数据的全面互联互通,打造台球行业领先的智能经营平台。 为什么加入众流 与传统工业设备公司不同,我们的产品直接面向真实商业场景。 研发人员不仅需要完成硬件开发,更需要思考: 如何提升门店经营效率 如何降低门店运营成本 如何提升用户体验 如何构建行业标准化解决方案 在这里,你参与的不只是一个控制板,而是一整套行业数字化生态。 你将有机会参与: 从 0 到 1 的新产品研发 软硬件一体化产品设计 智能设备联网方案设计 全国规模化落地项目 与团队一起推动台球行业的智能化升级。
嵌入式硬件工程师 薪资范围 12K-20K (能力优秀可面议) 工作地点 杭州 岗位职责 负责 DTU 、LoRa/4G 网关等物联网产品的硬件设计与开发; 负责产品原理图设计、PCB Layout 、器件选型、BOM 整理及硬件调试; 负责 LoRa 、4G Cat.1 、以太网等通信接口设计与调试; 负责 STM32 系列 MCU 外围电路设计与软硬件联调; 需要有一定的嵌入式软件开发能力; 输出设计文档、测试文档及生产资料。 任职要求 必须具备 2 年以上嵌入式硬件开发经验; 熟练使用 Altium Designer 进行原理图设计及 PCB 设计; 熟悉 STM32 、APM32 等 MCU 硬件设计; 熟悉 RS485 、UART 、SPI 、IIC 、CAN 等接口电路; 熟悉开关电源、电源管理、电磁兼容设计; 能独立完成产品从需求到样机的开发工作; 能熟练使用示波器、逻辑分析仪、万用表等调试工具。 加分项(重点关注) 满足任意两项以上优先录用: 做过 DTU 产品; 做过 LoRa 网关或 LoRa 节点; 做过 4G Cat.1 / NB-IoT 产品; 有软硬件独立开发经验; 能编写 STM32 驱动及简单业务逻辑代码; 使用过 RTOS ( freeRTOS\Threadx\RT-Thread)等。 不太匹配的方向 以下背景可作为参考,但优先级较低: 家电控制板 消费电子 PCB Layout 纯 EMC 工程师 纯测试工程师 纯软件工程师 电机控制工程师 无量产经验的应届生 关于团队/公司 众流是一家专注于台球行业数字化服务的科技企业,致力于通过软件系统与智能硬件的深度融合,推动台球门店经营管理的数字化升级。 目前,众流已为全国大量台球门店提供经营管理系统、会员系统、营销系统及数字化运营服务。随着业务发展,公司正在持续投入智能硬件产品研发,打造覆盖门店经营全场景的智能控制体系。 我们的研发方向包括: 台球桌智能控制系统 门店设备联网系统 4G/LoRa 通信设备 数据采集终端 边缘控制网关 灯光控制系统 自助营业设备 无人值守解决方案 未来,我们希望实现: 球桌、灯光、空调、门禁、收银、会员系统、经营数据的全面互联互通,打造台球行业领先的智能经营平台。 为什么加入众流 与传统工业设备公司不同,我们的产品直接面向真实商业场景。 研发人员不仅需要完成硬件开发,更需要思考: 如何提升门店经营效率 如何降低门店运营成本 如何提升用户体验 如何构建行业标准化解决方案 在这里,你参与的不只是一个控制板,而是一整套行业数字化生态。 你将有机会参与: 从 0 到 1 的新产品研发 软硬件一体化产品设计 智能设备联网方案设计 全国规模化落地项目 与团队一起推动台球行业的智能化升级。
IT之家 6 月 8 日消息,绿联 (UGREEN) 今日面向全球市场宣布了 NASync DXP GT 系列 NAS,其中既有此前国内市场已推出的 4+2 盘位型号 DXP4800 GT,还有本次新公布的 DXP2800 GT。 DXP2800 GT 也基于 AMD 锐龙嵌入式 R2514 处理器,不过 换用 2+2 盘位设计 ,运行 UGOS Pro 操作系统。 其配备 8GB DDR4 内存和 64GB eMMC 存储,提供 1 个 10GbE RJ45 、1 个 USB-C 10Gbps、2 个 USB-A 10Gbps、2 个 USB-A 480Mbps、1 个 HDMI 2.1 TMDS。 这款 NAS 在欧洲市场的建议零售价为 509.99 欧元 / 459.99 英镑(IT之家注:现汇率约合 3994 / 4169 元人民币);首发享受九折优惠,到手价 459.99 欧元 / 412.99 英镑(现汇率约合 3603 / 3743 元人民币)。
从 11 点多就开始让codex帮我梳理嵌入式课程知识点,给了他ppt 还有朋友发的复习资料,让他帮我按照wiki的方式梳理一下知识点。结果知识点生成的倒是很多,但内容真的是一言难尽。 就很多空话套话,在提示词里强调了也不行,用/目标 也表明了要一个知识点一个知识点整理,包含概念详尽、特点应用场景等,结果干了一个多小时跟原来几乎没啥变化。 最后让他自己给我搞一套提示词来整理,我又修改了一些到了最后还是一样,几乎没有可读性,全是废话。 也许跟我提示词写的太烂有关,也有可能一下给他的任务太多了,导致他没办法好好完成。 今天就到这吧,明天又是美好的一天 3 个帖子 - 3 位参与者 阅读完整话题
本帖使用社区开源推广,符合推广要求。我申明并遵循社区要求的以下内容: 我的帖子已经打上 开源推广 标签: 是 我的开源项目完整开源,无未开源部分: 是 我的开源项目已链接认可 LINUX DO 社区: 是 我帖子内的项目介绍,AI生成、润色内容部分已截图发出: 是 以上选择我承诺是永久有效的,接受社区和佬友监督: 是 以下为项目介绍正文内容,AI生成、润色内容已使用截图方式发出 一句话理解 本项目跟之前通过截图的方式去让AI理解不一样,本项目是直接将AD软件画好的原理图+PCB这个源文件直接做了解析输出AI看的懂的json格式(全部本地生成不用担心被窃取原理图PCB),这样去构建嵌入式程序可以实现百分百不会出错,就算你更新了原理图引脚只需要跟AI说一声就会自己去替换引脚。 原理图PCB读取 → 电路分析 → 固件生成 → Keil 构建 → 串口调试 → 工作流编排 开源项目地址: github.com GitHub - Tansuo2021/ADtoKeil 通过在 GitHub 上创建帐户来为 Tansuo2021/ADtoKeil 开发做出贡献。 如果对嵌入式开发有帮助,麻烦多多来帖子回应看看效果如何! 7 个帖子 - 4 位参与者 阅读完整话题
IT之家 6 月 5 日消息,据科技媒体 GizmoChina 昨天报道,高奢品牌 Caviar 现已推出“时间大师(Masters of Time)”限量版 iPhone 17 Pro Max 手机。新品拥有机械腕表收纳机构,可将瑞士名表直接“收纳”在手机后盖,起售价为 49640 美元(IT之家注:现汇率约合 33.7 万元人民币)。 据介绍,这款手机最独特的地方在于“腕表保险箱(Watch Vault)”设计, 其后背带有专门的腕表安装仓 ,可通过短螺纹锁定环固定腕表。无需任何工具、旋转锁扣即可将高端手表从手机中取出,然后安装普通表带戴在手上。 考虑到客户群体的手表通常价值连城, Caviar 特意在腕表收纳机构内加入柔软内衬 ,防止表壳、宝石装饰受损。如果用户决定将腕表戴在手上,也可以为手机安装装饰盖板,这样机身背面就不会留下一个大洞。 同时,该系列机型的“Celestial”版本自带 Patek Philippe Celestial 腕表,采用 18K 金、珐琅、钻石和陨石等名贵装饰物。用户还可选择劳力士、万国表、Jacob & Co.等限定版。 此外,该系列手机可嵌入 42-44mm 的机械名表,用户可根据自己的手表尺寸定制专属机身。
自从组里供给cc和codex之后,agent已经深度嵌入生活,一个也离不开。前几天codex被我一个误操作credential失效了,到今天才终于登上,这几天只有cc,简直跟瘸了条腿一样难受。 以后找组、工作的一项硬性要求就是老板提倡并提供/报销AI Agent等各类AI工具。 8 个帖子 - 6 位参与者 阅读完整话题
项目需要在 arm 设备上跑 ebpf 程序,现在设备还没有,于是买了定昌电子家的 rk3588 开发板进行程序开发和测试,但是很无奈地发现他们家提供的操作系统全部没有开启 ebpf 的完整支持,相对好的的 debian11 也没有开启 CONFIG_BPF_SYSCALL 和 CONFIG_BPF_JIT 参数。我自己不会编译内核,想找一个能提供完整 ebpf 支持操作系统的开发板厂家,求见多识广的 v 友们给点推荐。
首先,先说说我当前的现状:25届民办本科毕业生,24年嵌入式方面的培训,毕业之际开始投递简历. 可能是因为应届生好找工作,入职了一家100多人的小公司(没有大公司的流程,入职就开始debug),因为经过了半年多的培训,再加上ai,上手比较快,在职半年一直在debug,没有什么实质的项目. 在公司的下半年,也就是26年上半年,开始接手公司的项目开发,不过是比较简单的应用开发,底层接口都封装好了,我只需要调接口做应用逻辑就可以了,因为有ai的辅助,应用层很好写,出现问题修改问题,就这样缝缝补补,过了一年。 我25年六月毕业,现在是26年六月,公司使用的是ASR1605芯片为核心的模组,做了半年项目,实际这个应用开发没什么可以学习的东西,就是连服务器,服务器下发指令,设备响应。这个项目面临着量产,主要是接入客户的服务器,就量产然后给第二版需求,第二版做完还有第三版。 我的房子租的也是一年的,今年26年六月到期,不过因为我今天要出国去客户那里,房子我就延期了(单间,类似香港棺材房,而且不便宜) 今天去客户那里,我才了解了公司的制度情况,以及报销情况,客户是印度的, ,在国内下了班,去香港,坐晚上八点的飞机,到那边中国凌晨2点,南亚时间11:30。公司出差是没有任何补贴的,只报销路费和住宿费用,住宿自费的话,公司会补贴50元每晚 ,而且比较让我难受的是,我们老板单方面让去,然后催了我一周,客户那边才回应,(客户没有让来,老板单方面要求) 好了我要夜宿飞机了,我知道在佬们看来没什么,可是在深圳我工资不到1,还在cbd区域上班和租房。 我比较困惑的就是 1.学历确是会隐形的卡住脖子,我是民本计科,工作嵌入式软件,边工作边考研,电子信息专业,然后脱产三年,毕业转机器人或医疗行业,(我知道这个性价比比较低,时间成本太大了),硕士毕业,就业机会会更多。同时继续在这个公司工作一年,房子到期换房子。 2.直接再系统学习下32单片机,下了班学习,然后两三个月之后跳槽其他做st单片机的公司。(L站的大佬有学习资源 ) 3.其他方案,我能想到的就是考研跨平台,和学单片机跳槽相对来说大一点的公司 求佬们给一些建议,我真的很困惑很困惑 1 个帖子 - 1 位参与者 阅读完整话题
佬友们,我秋招签约到一家汽车零件厂的软件工程师,但是今天岗位分配表出来,我被分配到系统工程师了,有可能是我简历中关于系统管理的内容写太多了,被分配过去了。我想问一下佬友:系统工程师和嵌入式软件工程师在工作内容上有什么区别?现在事已至此也不好修改,我只想了解一下区别。有佬友是担任这两个岗位的吗? 1 个帖子 - 1 位参与者 阅读完整话题
4 个帖子 - 3 位参与者 阅读完整话题
我是一名双非硕士,目前研一,导师给的方向是深度学习,但是感觉不太好找工作,师兄也有做嵌入式的,但是老师说不太好发论文,我该如何选择和规划,如果是深度学习,我想在毕业找工作时有竞争力该做些什么,求佬们告知。 12 个帖子 - 12 位参与者 阅读完整话题
金融时报报道,腾讯正加紧在微信中推出一款嵌入式人工智能代理(AI agent),这款工具将深度集成于这款覆盖中国14亿人口、几乎囊括社交、支付与出行等各类功能的“超级应用”之中。据知情人士透露,腾讯已经在内部测试这一AI代理的原型产品,并计划最快在本月启动监管合规流程,为面向公众的正式上线做准备。 在合规审批之后,腾讯打算先在一小部分外部用户中进行试用,然后再分阶段逐步放量,具体的正式上线时间仍未确定,因为合规流程所需时间存在较大不确定性。在有关计划报道发布后,腾讯在香港上市的股价周二一度上涨6%,反映出资本市场对微信AI化进程的高度关注。 据一名看过早期演示的人士介绍,未来用户只需在微信主界面向右滑动,即可打开AI代理聊天窗口,通过自然语言输入指令。该代理可自动调用微信内数以百万计的小程序这一微信生态“地基”,帮助用户完成包括查找咖啡馆、按口味和价格偏好点单等在内的具体任务。 一旦在中国使用频率最高的应用中成功上线AI代理,腾讯有望借此在“智能体”落地方面实现对国内竞争对手的反超,尽管在大模型研发上其一度被同行视为起步偏慢的一方。目前,阿里巴巴已经将电商、旅行和地图等服务接入其通义千问(Qwen)AI应用,字节跳动则在旗下豆包应用中加入线上购物等“代理式”功能。 虽然通义千问和豆包的月活跃用户数量远不及拥有14亿用户的微信,但这两款产品增长迅速,给腾讯带来不小的时间压力。知情人士称,这也是腾讯迫切希望尽快推出微信AI代理的原因之一;目前,腾讯已在微信中嵌入具备搜索能力的聊天机器人“元宝”,但新一代AI代理将大幅提升自动化执行任务的能力。 一名了解内部决策的人士表示,腾讯已将微信AI代理的落地提升到公司最高战略优先级。但腾讯管理层在功能设计、安全与合规等各方面都极为谨慎,预计正式上线前会经历较长时间的灰度测试和多轮打磨迭代。 上述知情人士透露,从内部测试情况看,原型系统已经可以较为顺畅地完成各类任务,但真正面向十几亿用户大规模推开时,算力资源将成为突出挑战。在美国禁令出台前,中国互联网巨头主要依赖英伟达芯片建设AI数据中心,而相关高端芯片现已被禁止对中国出口。 该人士称,腾讯此前在英伟达芯片采购方面相对保守,并未在禁令前大量囤货,而本土半导体产能仍然紧张,这使得算力供给面临一定缺口。早期内部评估显示,在微信全量推开AI代理的成本将十分高昂,目前仍不清楚腾讯能否在短期内找到足够的商业化路径来覆盖这些投入。 自2011年以即时通讯工具起步以来,微信(中文名“微信”,对内亦称“微信/Weixin”)已经演变为深度嵌入中国日常生活方方面面的关键基础设施。依托由企业和政府机构开发、运营的小程序生态,用户可以在微信内完成餐饮外卖、缴纳水电费、挂号看病等大量日常事务,几乎无需跳出应用即可完成绝大多数日常交易。 这种高度一体化的产品形态,使腾讯得以从超过十亿用户身上积累庞大的行为数据,为训练与部署面向具体场景的“代理式AI”提供了数据基础。腾讯总裁刘炽平上月在财报电话会上表示,在通用基础模型之外,“代理型AI”越来越清晰地展现出颠覆性的应用前景,而腾讯的平台天然地适合作为AI代理的承载环境。 对于有关微信AI代理的具体计划及时间表,腾讯方面拒绝置评。报道同时指出,在算力、成本与合规审查多重约束之下,这一“微信智能体”能否以及何时全面落地,仍是外界关注的焦点。 查看评论
618快到了,想买电脑的心情达到了顶峰~ 个人情况是大学生,学嵌入式,目前有一台拯救者,性能完全够(除了非要本地部署大模型),但是太重了我一般都放在实验室了。回到宿舍后有还没跑完的项目还要用手机打开UU远程操作,本来就是用的小屏手机,还要操作电脑,简直难上加难。所以现在很想买一台电脑,但还没想好买哪台。 预算:穷苦大学生,尽量4000 5000… 我目前想到的: 1.Mac mini m4:我馋了好几个月了,可惜养虾潮直接炒飞了,见过了3000的全新m4,真的对4500的下不去手啊。现在好像pdd已经到4000了。 2.mac book air 不求新款,希望能淘到 3.win系统轻薄本:具体品牌我还没看,有同学用的鸡哥的轻薄本,具体型号我不知道,但也挺好用的,并且特别轻,手感很不错。 如果有佬有更具体的电脑型号,我是真的求推荐,或者我想的有什么不对的地方也请佬们指正我,求求了 5 个帖子 - 4 位参与者 阅读完整话题
📌 关于我们与项目 目前状态 :处于初创阶段,核心成员(我)深耕 软件开发多年 ,技术底座扎实。 产品方向 : 车载音乐盒子 (结合 AI 概念),旨在打造新一代的智能车载音频体验。 为什么限广深 :为了方便前期的线下深度交流。由于早期产品涉及 量产交付 ,深圳完善的硬件供应链是必不可少的,因此希望你 base 在 广州或深圳 (深圳尤佳)。 🛠 职位要求 (Your Role) 早期阶段,你需要 负责硬件的落地与实现 。我们希望你具备以下特质: 核心硬实力 :经验丰富的 嵌入式工程师 ,能独立搞定从方案选型、原理图/PCB 设计到固件开发的全流程。 加分项(优先考虑) : 汽车硬件背景 :做过车载电子产品(如车机、OBD 、车载配件等),熟悉车规级要求、电源管理或车内通讯者大加分。 音频产品经验 :做过播放器、音频解码、蓝牙音频、数字功放等音乐硬件产品者优先。 🤝 合作方式 (How We Work) 我们心态开放,尊重技术价值,形式可灵活支持: 方案 A (项目制) :按照项目里程碑直接结算现金报酬。 方案 B (合伙人制) :基础报酬 + 一定比例的期权/股权(适合看好 AI + 车载音频赛道,想一起搞点事情的长期伙伴)。 📥 怎么联系我 如果你对这个方向感兴趣,或者有朋友推荐,欢迎联系我详聊! wx : base64 encoded: Q3BoaWxv (加 wx 时请备注:姓名-嵌入式-广深)
📌 关于我们与项目 目前状态 :处于初创阶段,核心成员(我)深耕 软件开发多年 ,技术底座扎实。 产品方向 : 车载音乐盒子 (结合 AI 概念),旨在打造新一代的智能车载音频体验。 为什么限广深 :为了方便前期的线下深度交流。由于早期产品涉及 量产交付 ,深圳完善的硬件供应链是必不可少的,因此希望你 base 在 广州或深圳 (深圳尤佳)。 🛠 职位要求 (Your Role) 早期阶段,你需要 负责硬件的落地与实现 。我们希望你具备以下特质: 核心硬实力 :经验丰富的 嵌入式工程师 ,能独立搞定从方案选型、原理图/PCB 设计到固件开发的全流程。 加分项(优先考虑) : 汽车硬件背景 :做过车载电子产品(如车机、OBD 、车载配件等),熟悉车规级要求、电源管理或车内通讯者大加分。 音频产品经验 :做过播放器、音频解码、蓝牙音频、数字功放等音乐硬件产品者优先。 🤝 合作方式 (How We Work) 我们心态开放,尊重技术价值,形式可灵活支持: 方案 A (项目制) :按照项目里程碑直接结算现金报酬。 方案 B (合伙人制) :基础报酬 + 一定比例的期权/股权(适合看好 AI + 车载音频赛道,想一起搞点事情的长期伙伴)。 📥 怎么联系我 如果你对这个方向感兴趣,或者有朋友推荐,欢迎联系我详聊! wx : base64 encoded: Q3BoaWxv (加 wx 时请备注:姓名-嵌入式-广深)